从另一个字符串中删除字符串并生成所有可能的结果

时间:2015-12-11 16:53:15

标签: python algorithm search iteration

我似乎无法看到我的逻辑错误以及为什么它没有遍历所有可能的解决方案,任何人都可以看到我的错误吗?或者我是否完全倒退了这个问题并且有更好的方法?

例如,如果您获得abcabcb并被告知要删除ab,那么您可能的结果将是cabcb, bcacb, bcabc, abccb, abcbc在此问题中编辑您要删除的字符串必须保持有序,所以 ab与ba

不一样
given = abcabcb  
removed = ab  

XXcabcb  
XbcaXcb  
XbcabcX  
abcXXcb  
abcXbcX

我当前的代码会发现第一个答案两次,第二个答案,第三个答案,第一个答案,然后再发现第四个并停止。

打印输出,
    [0, 1, 'cabcb'] [0, 4, 'bcacb'] [0, 4, 'bcacb'] [0, 4, 'bcacb'] [0, 6, 'bcabc'] [0, 6, 'bcabc'] [0, 1, 'cabcb'] [3, 4, 'abccb'] [3, 4, 'abccb'] [3, 4, 'abccb']

,结果为['cabcb', 'cabcb', 'bcacb', 'bcacb', 'bcacb', 'bcabc', 'bcabc', 'cabcb', 'abccb', 'abccb', 'abccb']

python代码:

def hiddenMessage(given, remove):
    alist = []
    temp = []
    temp = oneHiddenMessage(given, remove)
    alist.append(temp[len(temp)-1])
    count = 0

    for i in range(len(remove)-1,-1,-1):
        for j in range(temp[i], len(given)):
            temp = oneHiddenMessagerec(given, remove, i, j)
            if temp == False:
                return alist
            alist.append(temp[len(temp)-1])
            print temp

def oneHiddenMessage(given, remove):
    message = ""
    index = 0
    counterR = 0 #what element in remove you are looking at
    returned = []
    for counterG in range(len(given)): #searches entire given word
        if counterR<len(remove): #makes sure hasn't gone beyond the elements of the string
            if given[counterG]==remove[counterR]: #if the character at position counterG of given is == as char at position counter R of remove skip over 
                counterR+=1 #increment counterR
                returned.append(counterG) #tracks the location of each char in removed relative to given
            else:
                message+=given[counterG] #if they aren't == add char to message
        else:
            message+=given[counterG] #if out of char from remove, throw rest of char onto message
    if len(message)!=(len(given)-len(remove)):
        return False #if not the expected size then not possible and throws false
    returned.append(message)
    return returned #returns locations of the removed char in respects to given and also the message


def oneHiddenMessagerec(given, remove, beingmoved, location):
    message = ""
    index = 0
    counterR = 0
    returned = []
    for counterG in range(len(given)):
        if counterR<len(remove):
            if given[counterG]==remove[counterR] and not (beingmoved==counterR and location>counterG): #checks whether they are the same element and not the same as the previous attempt
                counterR+=1
                returned.append(counterG)
            else:
                message+=given[counterG]

        else:
            message+=given[counterG]
    if len(message)!=(len(given)-len(remove)):
        return False

    returned.append(message)
    return returned

2 个答案:

答案 0 :(得分:0)

你的代码看起来太复杂了。但我建议采用另一种方法。您可以在第一个字符串中找到第二个字符串字符的所有匹配项。在您的示例中,这将导致这样的数组:[[0, 3], [1, 4, 6]]然后您应该删除所有对,使得第一个元素小于第二个元素[0,1],[0,4],[0,6],[3,4],[3,6]。这可以在递归函数的帮助下完成,从第一个列表中选择一个元素然后转到下一个列表并选择一个大于前一个列表元素的元素,依此类推。

0
.1
.4
.6
3
.1 # not good because 1<3
.4
.6

你可以这样概括这个方法:

first_string = "abcabcb"
second_string = "ab"
array = []
for c in second_string:
    arr = []
    for i,c2 in enumerate(first_string):
        if c2==c:
            arr.append(i)
    array.append(arr)
print array
def func(index,pre,s):
    if index == len(array):
        print s+first_string[pre+1:]
        return
    string = s
    p = 0
    while array[index][p]<pre:
        p+=1
        if p>=len(array[index]):
            return
    for i,c in enumerate(first_string):
        if p >=len(array[index]):
            return
        if i<=pre:
            continue
        if i == array[index][p]:
            func(index+1,i,string[:])
            string += c
            p+=1
        else:
            string += c
func(0,-1,"")

输出:

cabcb
bcacb
bcabc
abccb
abcbc

什么是func(0,-1,"")?它表示我们必须删除second_string[0]a,在这种情况下,其索引大于-1,我们的字符串到目前为止为""。然后在first_string[0]='a'时我们忽略它并调用func(1,0,""),因为我们已移除a,我们要删除其{1}},其索引&gt; 0,我们当前的字符串为second_string[1],因为我们没有添加""。同样,我们删除下一个a并调用b,这意味着我们删除了func(2,1,"")中的前两个字符,我们应该删除下一个字符,因为{{}中没有其他字符1}}我们将second_string中的所有剩余字符添加到second_string并打印出来。之后,我们返回first_string中的一个步骤,并尝试找到下一个current_string,因为下一个func(1,0,"")出现在索引b (second_string[1]),我们将b添加到4 {1}}并调用first_string[1,2,3] ...此例程将继续,直到找到所有可能的字符串。

答案 1 :(得分:0)

另一个Pythonic解决方案是在第一个字符串中创建第二个字符串字符出现的数组,并使用itertools.product创建所有增加的组合并从第一个字符串中删除它们:

first_string = "abcabcb"
second_string = "ab"
array = []
for c in second_string:
    arr = []
    for i,c2 in enumerate(first_string):
        if c2==c:
            arr.append(i)
    array.append(arr)
from itertools import product
f = lambda x: all( [x[i-1]<x[i] for i in range(1,len(x))])
combs = list(filter(f,product(*array)))     
for item in combs:
    string = ""
    for i in range(len(first_string)):
        if i not in item:
            string += first_string[i]
    print string