Algorithm 将序列转换为lex顺序

Algorithm 将序列转换为lex顺序,algorithm,sequences,Algorithm,Sequences,我有一个函数,可以生成一个固定数目为1的二进制序列(其余为0)。我需要一个函数,它接受一个序列并按字典顺序返回该序列的位置。例如,10个长度为5且带有3个1的序列是 0 0 1 1 1 0 1 0 1 1 0 1 1 0 1 0 1 1 1 0 1 0 0 1 1 1 0 1 0 1 1 0 1 1 0 1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 我需要一个函数,它接受例如01101并返回3,因为它是列表中的第三个 我能想到的唯一一件事,效率太低,就是生成所有序列(简单),存储

我有一个函数,可以生成一个固定数目为1的二进制序列(其余为0)。我需要一个函数,它接受一个序列并按字典顺序返回该序列的位置。例如,10个长度为5且带有3个1的序列是

0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
0 1 1 1 0
1 0 0 1 1
1 0 1 0 1
1 0 1 1 0
1 1 0 0 1
1 1 0 1 0
1 1 1 0 0
我需要一个函数,它接受例如
01101
并返回
3
,因为它是列表中的第三个


我能想到的唯一一件事,效率太低,就是生成所有序列(简单),存储它们(占用太多空间),然后在列表中搜索给定序列(太慢),然后返回其位置。有没有更快的方法?一些我没有看到的简单技巧?

我们称长度为
n
的序列集为
k
1的
binseq(n,k)
。然后可以递归地解决此问题,如下所示:

  • 基本情况:如果
    S
    的长度为1,则它位于位置1
  • 如果
    S
    以0开头,则其位置与
    binseq(n-1,k)
    尾部的位置相同(
    S
    ,删除第一个元素)
  • 如果
    S
    以1开头,其位置等于
    binseq(n-1,k-1)
    尾部的位置加上
    binseq(n-1,k)
    中的序列数
  • 在python代码中:

    #!/usr/bin/env python
    
    def binom(n, k):
        result = 1
        for i in range(1, k+1):
            result = result * (n-i+1) / i
        return result
    
    def lexpos(seq):
        if len(seq) == 1:
            return 1
        elif seq[0] == 0:
            return lexpos(seq[1:])
        else:
            return binom(len(seq)-1, seq.count(1)) + lexpos(seq[1:])
    
    或者像阿披舍克·班萨尔(Abhishek Bansal)所建议的迭代版本:

    def lexpos_iter(seq):
        pos = 1
        for i in xrange(len(seq)):
            if seq[i] == 1:
                pos += binom(len(seq)-i-1, seq[i:].count(1))
        return pos
    

    好主意!它也可以迭代进行,例如对于S=1010100,位置=C(6,3)+C(4,2)+C(2,1)+1=29。