Algorithm 将序列转换为lex顺序
我有一个函数,可以生成一个固定数目为1的二进制序列(其余为0)。我需要一个函数,它接受一个序列并按字典顺序返回该序列的位置。例如,10个长度为5且带有3个1的序列是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,因为它是列表中的第三个 我能想到的唯一一件事,效率太低,就是生成所有序列(简单),存储
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,则它位于位置1S
以0开头,则其位置与binseq(n-1,k)
中尾部的位置相同(S
,删除第一个元素)
S
以1开头,其位置等于binseq(n-1,k-1)
中尾部的位置加上binseq(n-1,k)
中的序列数
#!/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。