[英]Iteratively insert a character into different indeces of a string
我正在尝试制作一个 Python 程序,该程序从头到尾迭代地插入 1 个点,然后从头到尾插入 2 个点,等等。例如,给定一个字符串abcd
,我想生成['abcd', 'a.bcd', 'abcd', 'abc.d', 'a.bc.d', 'ab.cd', 'ab.c.d', 'abc.d']
。 因此,对于长度为n
的字符串,我想在字符串中添加n-1
点。
我的代码完全用于添加最多 3 个点,但假设我有一个长度为 101 的字符串并想要添加 100 个点,这意味着我必须输入 100 个 for 循环。 这是可行的,但我在想可能有更好的方法来做到这一点,所以我想知道你的想法!
my_list = []
my_string = "abcd"
my_list.append(my_string) # 0 dots
length = len(my_string)
for i in range(1, length, 1): # insert 1 dot from beginning to end
new_string = my_string[0:i] + "." + my_string[i:]
my_list.append(new_string)
for j in range(i+1, length, 1): # insert 2 dots from beginning to end
new_string = my_string[0:i] + "." + my_string[i:j] + "." + my_string[j:]
my_list.append(new_string)
for k in range(j+1, length, 1): # insert 3 dots from beginning to end
new_string = my_string[0:i] + "." + my_string[i:j] + "." + my_string[j:k] + "." + my_string[k:]
my_list.append(new_string)
print(my_list)
我希望我现在不解决你的全部学校作业:) 对于两个字符之间的每个 position,你要么有一个点,要么没有,我们可以将其表示为 0 或 1。对于“abc”,这可以是:
abc = 00
ab.c = 01
a.bc = 10
abc = 11
这基本上是二进制计数。 我们需要列出所有 integer 值高达 2^(n)-1,其中 n 是字符串的长度 - 1。从这些值中,您可以生成所有这些字符串。 一些好的旧按位逻辑会有所帮助。
def list_dots(x):
n = 1 << max(0, len(x) - 1)
for i in range(n):
o = ''
for c in x:
o += c
if i & 1:
o += '.'
i >>= 1
yield o
示例 output
>>> list(list_dots('a'))
['a']
>>> list(list_dots('ab'))
['ab', 'a.b']
>>> list(list_dots('abc'))
['abc', 'a.bc', 'ab.c', 'a.b.c']
>>> list(list_dots('abcd'))
['abcd', 'a.bcd', 'ab.cd', 'a.b.cd', 'abc.d', 'a.bc.d', 'ab.c.d', 'a.b.c.d']
如果您发送一个大字符串,output 将变得相当大,因为它会增长 O(2^x),其中 x 是字符串的长度。
my_s = "abcdefg"
def enter_dots(s, num_dots):
if num_dots == 0:
return [s]
results = [s]
lst = list(s)
for i in range(1, len(lst)):
possibility = list(lst)
possibility.insert(i, ".")
# if two dots in same place, disregard possibility
if possibility[i + 1] == "." or possibility[i - 1] == ".":
continue
str_possibility = "".join(possibility)
results.append(str_possibility)
results.extend(enter_dots(str_possibility, num_dots - 1))
return results
print(sorted(list(set(enter_dots(my_s, 3)))))
在点数上递归。
如果不需要点,则返回仅包含输入字符串的列表。
否则,迭代该字符串并在每个可能的位置添加点。
将该字符串发送回enter_dots
,需要少一个点。
最后,杀死重复项( set
)并sort
以提高可读性。
Output:
['abc.defg','abcd.efg','abcde.fg','abcdef.g','abcdefg','a.bc.d.efg','a.bc.de.fg',' a.bc.def.g'、'a.bc.defg'、'a.bcd.e.fg'、'a.bcd.ef.g'、'a.bcd.efg'、'a.bcde。 f.g','a.bcde.fg','a.bcdef.g','a.bcdefg','ab.c.d.efg','ab.c.de.f' c.def.g','ab.c.defg','ab.cd.e.fg','ab.cd.ef.g','ab.cd.efg','ab.cde.f。 g','ab.cde.fg','ab.cdef.g','ab.cdefg','abc.defg','abc.d.ef.g','abc.d.efg',' abc.de.f.g'、'abc.de.fg'、'abc.def.g'、'abc.defg'、'abcd.efg'、'abcd.e.fg'、'abcd.ef. g','abcd.efg','abcde.f.g','abcde.fg','abcdef.g','abcdefg']
如果您最初想删除重复项,可以通过多种方式完成,例如使用dict
这是使用来自itertools的product
chain
和zip_longest
的解决方案
>>> from itertools import product, chain, zip_longest
>>> s = 'abcd'
>>> for p in product(['','.'],repeat=len(s)-1):
print(''.join(chain.from_iterable(zip_longest(s, p,fillvalue=''))))
abcd
abc.d
ab.cd
ab.c.d
a.bcd
a.bc.d
a.b.cd
a.b.c.d
lst = []
str = 'abcdefg'
strlst = list(str)
lst.append(str)
# Inserts a dot in between the characters
for i in range(1, (len(strlst)*2)-1, 2):
strlst.insert(i, '.')
lst.append(''.join(strlst))
print(lst)
# removes the dots from those characters
for i in range(1, (len(str))-1):
del strlst[i]
lst.append(''.join(strlst))
print(lst)
Output:
['abcdefg', 'a.bcdefg', 'abcdefg', 'abc.defg', 'abc.d.efg', 'abc.defg', 'abc.defg']
['abcdefg', 'a.bcdefg', 'abcdefg', 'abc.defg', 'abc.d.efg', 'abc.defg', 'abc.defg', 'ab.c.defg', ' abc.defg','abcd.efg','abcde.f.g','abcdef.g']
不知道你在找什么,但希望这会有所帮助
使用迭代工具:
from itertools import permutations
string = 'abcd'
{string[0]+''.join(i)+string[-1]
for dots in range(1, len(string))
for i in permutations(string[1:-1]+'.'*dots)
if ''.join(i).replace('.','') == string[1:-1] and '.'*2 not in ''.join(i)}
输出:
{'a.b.c.d', 'a.b.cd', 'a.bc.d', 'a.bcd', 'ab.c.d', 'ab.cd', 'abc.d'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.