我无法在以下方面找到合适的答案:
假设我有以下返回的LONG int(或任何字符串):
longnr = 26731623516244147357200698985770699644500911065919594945175038371437093557337774208653
我可以通过以下方式轻松拆分:
splitnr = [26731,62351,624,41,4735,720,0698,9857,7069,964,450,091,10659,195,94,94517,5038,3714,3709,35,573,37,7,74208653]
每种组合都是独一无二的,因此没有重复的数字。 我在简单的代码中执行此操作,只需迭代每个项目并将它们添加到字符串中,直到找到重复的数字。然后只需将此字符串写入列表,空字符串,添加刚检查过的数字,然后继续,直到完成所有操作。
我想要的是尽可能少的组合。 因此,首先尝试找到所有10个数字的唯一组合,然后查找剩下的9个,8,7等等。
我需要正则表达式吗? 我无法完成这项工作,有些人建议我需要大量的模式。
下一个选项:
len(set(str(longnr)[0:10])) == len(str(longnr)[0:10])
这适用于前10个检查它是否唯一。
如何以最佳方式离开这里? 订单必须像splitnr一样保留。
答案 0 :(得分:1)
我确信爱德华彼得斯得到了答案。但从经验上看,似乎所有三种解决方案都同样出色:
from random import choice
def edward_peters(string):
sequences = [[]]
for end in range(1, len(string) + 1):
def candidate_sequences():
for previous_end in range(max(0, end - 10), end):
substring = string[previous_end:end]
if len(substring) == len(set(substring)):
yield sequences[previous_end] + [substring]
sequences.append(min(candidate_sequences(), key=len))
return sequences[-1]
def brendan_abel(long_string):
if not long_string:
return []
cur_i = None
cur_s = None
max_i = None
max_s = None
for i, s in enumerate(long_string):
if cur_s is None or s in cur_s:
if cur_s and (max_s is None or len(cur_s) > len(max_s)):
max_i = cur_i
max_s = cur_s
cur_i = i
cur_s = [s]
else:
cur_s.append(s)
else:
if cur_s and (max_s is None or len(cur_s) > len(max_s)):
max_i = cur_i
max_s = cur_s
before = long_string[:max_i]
after = long_string[max_i + len(max_s):]
return brendan_abel(before) + [''.join(max_s)] + brendan_abel(after)
def ruud(string):
result = []
current = ''
for c in string:
if c in current:
result.append(current)
current = c
else:
current += c
result.append(current)
return result
def main():
while True:
string = ''.join(choice('1234567890') for _ in range(10000))
results = [func(string) for func in [edward_peters, brendan_abel, ruud]]
assert all(''.join(result) == string for result in results)
assert len(set(map(len, results))) == 1
main()
我根本无法直观地理解这一点。似乎Brendan Abel对Edward Peters'解决方案是OP倒退,例如
print edward_peters(string)
['49', '9', '3849', '3089', '91', '1', '15', '58', '42876', '81926', '6720', '90', '0', '27103', '3064', '436', '6', '862', '2', '201', '7091', '912', '23', '6345', '582', '382', '2', '82457', '64937', '0574', '2743', '983', '4382']
答案 1 :(得分:0)
你可以使用递归函数来做到这一点,它会像分而治之的排序算法一样工作。最糟糕的情况是O(n^2)
(好吧,它基本上总是O(n^2)
)
浏览原始列表中的每个元素并尝试制作最长的唯一链,存储最大链的起始索引(我们可以在这里作弊,因为我们知道10是绝对最大值,仅使用数字和我们一找到10长的链就停止了,但我在下面的例子中没有这样做。)
将列表拆分为2个单独的列表,一个列在我们刚找到的元素列表之前,另一个列在之后,并将它们都输入到递归函数中。
重新组合结果
下面的函数假设你传递了一个字符串,所以首先将你的长号字符串化,然后将字符串转换回数字。
def func(long_string):
if not long_string:
return []
cur_i = None
cur_s = None
max_i = None
max_s = None
for i, s in enumerate(long_string):
if cur_s is None or s in cur_s:
if cur_s and (max_s is None or len(cur_s) > len(max_s)):
max_i = cur_i
max_s = cur_s
cur_i = i
cur_s = [s]
else:
cur_s.append(s)
else:
if cur_s and (max_s is None or len(cur_s) > len(max_s)):
max_i = cur_i
max_s = cur_s
before = long_string[:max_i]
after = long_string[max_i + len(max_s):]
return func(before) + [''.join(max_s)] + func(after)
long_number = 1233423732174096361032409234987352
list_of_strings = func(str(long_number).strip('L')) # strip L for older python versions.
list_of_numbers = map(int, list_of_strings)