繁体   English   中英

迭代地将一个字符插入到字符串的不同索引中

[英]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

这是使用来自itertoolsproduct chainzip_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM