Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 随机访问固定字母表中3个符号的已排序集合的枚举_Algorithm_Sorting_Combinatorics - Fatal编程技术网

Algorithm 随机访问固定字母表中3个符号的已排序集合的枚举

Algorithm 随机访问固定字母表中3个符号的已排序集合的枚举,algorithm,sorting,combinatorics,Algorithm,Sorting,Combinatorics,假设我们有一个字母表,比如说5个字符:ABCDE 我们现在要列举其中3个字母的所有可能集合。每个字母在一个集合中只能出现一次,字母的顺序无关紧要(因此集合中的字母应该被排序) 因此,我们得到以下集合: ABC 阿布德 阿贝 ACD 王牌 艾德 卡介苗 BCE 溴化二苯醚 CDE 总共10套。顺序是按词典编纂的 现在,我们假设字母表长度为N(本例中为5),集合长度为M(本例中为3)。知道N和M,如果可能的话,我们怎么可能: 告诉最坏情况下组合的总数O(M+N)(本例中的答案是10) 在最坏情况下输

假设我们有一个字母表,比如说5个字符:ABCDE

我们现在要列举其中3个字母的所有可能集合。每个字母在一个集合中只能出现一次,字母的顺序无关紧要(因此集合中的字母应该被排序)

因此,我们得到以下集合:

  • ABC
  • 阿布德
  • 阿贝
  • ACD
  • 王牌
  • 艾德
  • 卡介苗
  • BCE
  • 溴化二苯醚
  • CDE
  • 总共10套。顺序是按词典编纂的

    现在,我们假设字母表长度为
    N
    (本例中为5),集合长度为
    M
    (本例中为3)。知道
    N
    M
    ,如果可能的话,我们怎么可能:

  • 告诉最坏情况下组合的总数
    O(M+N)
    (本例中的答案是10)
  • 在最坏情况下输出任意给定数字的组合(给定1,返回ABC;给定5,返回ACE等)
    O(M+N)

  • O(M^N)
    复杂度生成整个列表是很简单的,但我想知道是否有更好的解决方案。

    第一个问题的答案很简单:它是
    C(N,r)
    ,我们要从一组大小
    N
    中选择
    r
    项的所有组合。公式包括:

    C(n,r) = n! / (r! (n-r)!)
    
    选择第i个组合而不计算所有其他组合的能力取决于是否具有将组合编号i与组合关联的编码。这将是更具挑战性的,需要更多的思考

    (编辑)

    仔细考虑这个问题后,Python中的解决方案如下所示:

    from math import factorial
    
    def combination(n,r):
        return factorial(n) / (factorial(r) * factorial(n-r))
    
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    def showComb(n,r,i,a):
        if r < 1:
            return ""
        rr = r-1
        nn = max(n-1,rr)
        lasti = i
        i -= combination(nn,rr)
        j = 0
        while i > 0:
            j += 1
            nn = max(nn-1,1)
            rr = min(rr,nn)    # corrected this line in second edit
            lasti = i
            i -= combination(nn,rr)
        return a[j] + showComb(n-j-1,r-1,lasti,a[(j+1):])
    
    for i in range(10):
        print(showComb(5,3,i+1,alphabet))
    
    。。。这证实了这120个例子都是正确的


    我还没有精确计算时间复杂度,但是对
    showComb()
    的调用次数将是
    r
    ,而
    while
    循环将执行
    n
    次或更少。因此,在这个问题的术语中,如果我们假设
    factorial()
    函数可以在恒定时间内计算,我非常确定复杂性将小于O(M+N),我认为这不是一个糟糕的近似,除非它的实现是幼稚的

    第一个问题的答案很简单:它是
    C(n,r)
    ,我们从一组大小
    n
    中选择
    r
    项的所有组合。公式包括:

    C(n,r) = n! / (r! (n-r)!)
    
    选择第i个组合而不计算所有其他组合的能力取决于是否具有将组合编号i与组合关联的编码。这将是更具挑战性的,需要更多的思考

    (编辑)

    仔细考虑这个问题后,Python中的解决方案如下所示:

    from math import factorial
    
    def combination(n,r):
        return factorial(n) / (factorial(r) * factorial(n-r))
    
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    def showComb(n,r,i,a):
        if r < 1:
            return ""
        rr = r-1
        nn = max(n-1,rr)
        lasti = i
        i -= combination(nn,rr)
        j = 0
        while i > 0:
            j += 1
            nn = max(nn-1,1)
            rr = min(rr,nn)    # corrected this line in second edit
            lasti = i
            i -= combination(nn,rr)
        return a[j] + showComb(n-j-1,r-1,lasti,a[(j+1):])
    
    for i in range(10):
        print(showComb(5,3,i+1,alphabet))
    
    。。。这证实了这120个例子都是正确的


    我还没有精确计算时间复杂度,但是对
    showComb()
    的调用次数将是
    r
    ,而
    while
    循环将执行
    n
    次或更少。因此,在这个问题的术语中,如果我们假设
    factorial()
    函数可以在恒定时间内计算,我非常确定复杂性将小于O(M+N),我认为这不是一个糟糕的近似,除非它的实现是幼稚的

    同意第一部分很简单,用你选择的语言表达类似的等式

    x=12
    y=5
    z=1
    base=1
    until [[ $z -gt y ]]
    do
     base=`echo $x $z $base|awk '{print ($1/$2) * $3}'`
     x=`expr $x - 1`
     z=`expr $z + 1`
     echo base:$base
    done
    
    echo $base
    
    上面的示例使用了12个项目,以5个为一组,用于792个组合


    做你问题的第二部分。。。我只是在想,但它不是直截了当的。

    同意第一部分很简单,用你选择的语言表达类似的等式

    x=12
    y=5
    z=1
    base=1
    until [[ $z -gt y ]]
    do
     base=`echo $x $z $base|awk '{print ($1/$2) * $3}'`
     x=`expr $x - 1`
     z=`expr $z + 1`
     echo base:$base
    done
    
    echo $base
    
    上面的示例使用了12个项目,以5个为一组,用于792个组合


    做你问题的第二部分。。。我只是在想,但它不是直截了当的。

    看起来很棒!我一直在修改您的解决方案,并尝试将I范围(120):打印(showComb(10,3,I+1,字母表))的循环更改为
    。但它会产生错误的组合和崩溃。@dragonroot:谢谢您的测试!是的,当
    n-r
    大于2时,代码中出现了一个bug。我已经在上面编辑的答案中更正了。看起来很棒!我一直在修改您的解决方案,并尝试将I范围(120):打印(showComb(10,3,I+1,字母表))的循环更改为
    。但它会产生错误的组合和崩溃。@dragonroot:谢谢您的测试!是的,当
    n-r
    大于2时,代码中出现了一个bug。我已经在上面编辑的答案中更正了它。