python唯一字符串创建
我已经研究了其他几个与此“类似”的SO问题(以及谷歌的问题),但它们似乎都不符合我的问题 我试图创建一个非固定长度、唯一的文本字符串,在我指定的字符串中只包含字符。例如,由大写字母和小写字母a-zA-Z组成。(对于本例,我仅使用a、b和c小写) 类似这样的内容(下面是断开的代码) index参数将是与文本字符串相关的索引(整数),例如:python唯一字符串创建,python,algorithm,python-2.7,Python,Algorithm,Python 2.7,我已经研究了其他几个与此“类似”的SO问题(以及谷歌的问题),但它们似乎都不符合我的问题 我试图创建一个非固定长度、唯一的文本字符串,在我指定的字符串中只包含字符。例如,由大写字母和小写字母a-zA-Z组成。(对于本例,我仅使用a、b和c小写) 类似这样的内容(下面是断开的代码) index参数将是与文本字符串相关的索引(整数),例如: next(1) == 'a' next(2) == 'b' next(3) == 'c' next(4) == 'aa' next(5) == 'a
next(1) == 'a'
next(2) == 'b'
next(3) == 'c'
next(4) == 'aa'
next(5) == 'ab'
next(6) == 'ac'
next(7) == 'ba'
next(8) == 'bb'
next(9) == 'bc'
next(10) == 'ca'
next(11) == 'cb'
next(12) == 'cc'
等等。字符串:
from itertools import combinations_with_replacement, chain
chars = 'abc'
a = chain(*(combinations_with_replacement(chars, i) for i in range(1, len(chars) + 1)))
基本上,此代码创建了一个迭代器,该迭代器将长度为1
,2
,…,len(chars)
的chars的所有组合组合组合在一起
a:print x中x的输出为:
('a',)
('b',)
('c',)
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
您不能将索引与烦人的内容真正“关联”,但以下是一个生成器,它将生成并提供您所要求的输出:
from itertools import combinations_with_replacement
def uniquenames(chars):
for i in range(1, len(chars)):
for j in combinations_with_replacement(chars, i):
yield ''.join(j)
print list(uniquenames('abc'))
# ['a', 'b', 'c', 'aa', 'ab', 'ac', 'bb', 'bc', 'cc']
您要做的是将next
函数的参数写入另一个基中
假设validCharacters
包含k
个字符:那么next
函数的任务是使用validCharacters
中的字符将参数p
转换为基k
在您的示例中,您可以将数字写在基数3中,然后将每个数字与一个字母关联:
next(1) -> 1 -> 'a'
next(2) -> 2 -> 'b'
next(4) -> 11 -> 'aa'
next(7) -> 21 -> 'ba'
等等
使用此方法,您可以调用next(x)
,而无需知道或计算任何next(x-i)
,这是迭代方法无法做到的。因此,您似乎正在尝试枚举语言{a'、'b'、'c}生成的所有字符串。这可以通过使用来完成(尽管您不想这样做)。通过该语言枚举的一种简单方法是从一个列表开始,按顺序追加所有长度为1的字符串(因此a、b、c)。然后将字母表中的每个字母附加到长度为n-1的每个字符串上。这将保持它的有序性,只要您将字母表中的所有字母附加到给定的字符串,然后再转到按字典顺序排列的下一个字符串。据我所知,我们不应该指定输出字符串的最大长度。所以范围是不够的:
>>> from itertools import combinations_with_replacement, count
>>> def u(chars):
... for i in count(1):
... for k in combinations_with_replacement(chars, i):
... yield "".join(k)
...
>>> g = u("abc")
>>> next(g)
'a'
>>> next(g)
'b'
>>> next(g)
'c'
>>> next(g)
'aa'
>>> next(g)
'ab'
>>> next(g)
'ac'
>>> next(g)
'bb'
>>> next(g)
'bc'
您试图将一个数字转换为另一个基数中的数字,但该基数的数字使用任意字符
import string
chars = string.lowercase + string.uppercase
def identifier(x, chars):
output = []
base = len(chars)
while x:
output.append(chars[x % base])
x /= base
return ''.join(reversed(output))
print identifier(1, chars)
这可以让你跳到任何位置,你正在计数,因此标识符是完全唯一的,并且很容易使用任何长度(两个或更多)的字符集,数字越小,标识符越短。@Blender谢谢,刚刚意识到它缺少一些标识符。。。需要修正+1,让我觉得自己像个傻瓜。几个月前,我在很长一段时间内解决了这个问题,这是一个可怕的任务:)这个问题比那个要简单得多。注意迭代的答案。虽然它们可能会起作用,但如果您想返回上次停止的位置而不重新计算所有以前的值,则必须存储状态。@Blender我认为在这种情况下,迭代的答案解决不了正确的问题。反向的
在这里甚至没有必要,因为您只担心长度,而不担心顺序。不过要小心:标识符(123456789,chars)
返回已接受(和+1'd?)这正是我所需要的,我也很欣赏它的实现。我知道它是这样的,只是我一根手指都插不上!@JonClements什么版本的Python?在2.7agf上对我来说很好:你知道你的函数永远不会返回一个以“a”开头的超过一个字符长的字符串,对吗?你可以做得更好一点,但是你知道吗你必须使用非标准的基本系统。+1对于idea,我需要看一些基本实现或psuedo代码来理解它。
import string
chars = string.lowercase + string.uppercase
def identifier(x, chars):
output = []
base = len(chars)
while x:
output.append(chars[x % base])
x /= base
return ''.join(reversed(output))
print identifier(1, chars)