我有一个函数可以生成固定数为1的二进制序列(其余为0)。我需要一个函数,它接受一个序列并以字典顺序返回该序列的位置。例如,长度为5且具有3 1的10个序列是
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
我需要一个函数,例如0 1 1 0 1
并返回3
,因为它是列表中的第三个。
我能想到的唯一一个效率太低的方法是生成所有序列(简单),存储它们(占用太多空间),然后在列表中搜索给定的序列(太慢) ,并返回其立场。有更快的方法吗?我看不到一些简单的伎俩?
答案 0 :(得分:3)
我们使用n
1 k
调用长度为binseq(n,k)
的序列集。然后可以递归地解决这个问题,如下所示:
S
长度为1,则位于第1位。S
以0开头,则其位置与tail(S)
中S
(binseq(n-1, k)
移除第一个元素的位置)相同。S
以1开头,则其位置等于tail(S)
中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