我不知道如何有效地提出这个问题但是我需要做的是将字符的整数值分配给字符,使得字符的加法不等于第一个加上第二个而是下一个数字。序列。
例如:
如果我使用ascii值将a-z设置为1-26那么如果我有字符串ab
则总和将为3
不过,我希望ab
被分配27
,ac = 28
,ad = 29
等。
所以a = 1
只有az = 51
(而不是27,如果我只是做a + z
)
我不确定这是否会影响解决方案,但其中一个条件是字符串中的字母必须按字母顺序排列,因此字符串可以是“abc
”但不能是“{{ 1}}“
谢谢!
答案 0 :(得分:1)
可以以所请求的方式计算索引,而无需构建所有可能字符串的列表,但这样做有点牵连。以下是执行此操作的有效方法的实现:
import itertools
import string
letters = string.ascii_lowercase
def _reference(max_len=4):
"""A reference implementation of the desired index operation."""
a = []
for k in range(max_len + 1):
for comb in itertools.combinations(letters, k):
a.append("".join(comb))
return a.index
def choose(n, k):
"""The binomial coefficient "n choose k"."""
if k < 0:
return 0
result = 1
for i in range(k):
result *= n - i
result //= i + 1
return result
def index(s):
"""An efficient implementation of the index operation."""
n = len(s)
choices = len(letters)
result = 0
for i, c in enumerate(s):
new_choices = len(letters) - letters.index(c)
result += choose(choices, n - i) - choose(new_choices, n - i)
choices = new_choices - 1
for i in range(n):
result += choose(len(letters), i)
return result
test_strings =[
"a", "j", "ab", "az", "jw", "yz", "abc", "abhors", "almost",
"begins", "bijoux", "biopsy", "chimps", "chinos", "chintz"]
ref_index = _reference(max(map(len, test_strings)))
for s in test_strings:
print "{0:8}{1:8}{2:8}".format(s, index(s), ref_index(s))
此脚本将高效函数的输出与强力实现进行比较,输出为
a 1 1
j 10 10
ab 27 27
az 51 51
jw 228 228
yz 351 351
abc 352 352
abhors 91047 91047
almost 133902 133902
begins 154337 154337
bijoux 171130 171130
biopsy 172655 172655
chimps 201678 201678
chinos 201734 201734
chintz 201781 201781