字符串操作递归函数

时间:2018-12-10 13:00:17

标签: python string python-3.x recursion

努力实现递归转换功能,该功能将从字符串中删除连续的重复字母...

例如"abbabcc" => "aabcc"(在第一遍,删除"bb"

例如"aabcc" => "bcc"(第二遍,删除"aa"

,然后递归调用自身,直到最终减少量类似于"abbabcc" => "b"

def transformations(J):
    if len(J) == 1:
        return J
    front_part = ""
    back_part = ""
    if J[0] == J[1]:
        back_part += J[2:]
        return transformations(back_part)
    else: 
        front_part += J[0]
        back_part += J[1:]
        return front_part + transformations(back_part)

assert transformations("ab") == "ab"
assert transformations("aba") == "aba"
assert transformations("abc") == "abc"
assert transformations("aabbbccaaba") == "a"


assert transformations("abba") == "" 
# "abba" should return "aa" on first pass then return empty string 
# on second pass, but right now it returns "aa" and stops there

现在,以上算法适用于大多数输入,但中间有两次连续的输入会在删除第一个连续的输入后产生另一个两次连续的输入,例如("abba")

如果要解决这个问题,我需要一个基础,但我无法弄清楚,我的算法有问题吗?

3 个答案:

答案 0 :(得分:2)

您需要转换,直到input == result。当input == result时,意味着它无法再转换。参见下面的更改。

def transformations(J):
    if len(J) <= 1: # I made it less than or equal
        return J
    front_part = ""
    back_part = ""
    if J[0] == J[1]:
        back_part = J[2:]
        return transformations(back_part)
    else: 
        front_part = J[0]
        back_part = J[1:]
        # See below
        result =  front_part + transformations(back_part)
        # If it's same we have done all transformations.
        if result == J:
            return result
        else: # try to perform more transformations
            return transformations(result)

tests = [
    ["abba", ""],
    ["ab", "ab"],
    ["aba", "aba"],
    ["aabbbccaaba", "a"]
]

for inp, expected in tests:
    actual = transformations(inp)
    print("trans(%s) == %s" % (inp, actual), "Test Passed =", actual == expected)

这将导致

trans(abba) ==  Test Passed = True
trans(ab) == ab Test Passed = True
trans(aba) == aba Test Passed = True
trans(aabbbccaaba) == a Test Passed = True

答案 1 :(得分:1)

针对您的上述问题,正如@Bhathiya Perera的注释所强调的那样,进行递归调用需要退出条件,首先,这样您的代码不会永远运行,而且还可以定义令人满意的返回值。

在您的情况下,退出条件是该字符串不再包含可扩展到的重复项,我无法删除更多字符,或者input_string = output_string。

进一步的评论是,如果退出条件定义得当,则可以用于循环,而不必担心对函数的无休止调用。

def remove_adjacent_duplicates(input_string): 
    '''
    Function removes adjacent duplicates recursively
    '''
    string_length = len(input_string)
    # If length of string is 1 or 0 then there are no duplicates present
    if string_length == 0 or string_length == 1: 
        return input_string 

    # Iterate through the string to remove all duplicates present in first pass
    # Note that the range goes from 1 -> len-1 to avoid boundary errors
    for i in range(1, string_length - 1):
        if input_string[i-1] == input_string[i]:
            # Remove duplicates by slicing the string around the duplicates
            new_string = input_string[:i - 1] + input_string[i + 1:]
            print new_string

    if new_string == input_string:
        #  Define the exit condition 
        return input_string
    else:
        # Recursive call if there have been duplicate removals
        # This will do a final call to ensure no more duplicates remain 
        return remove_adjacent_duplicates(new_string)

答案 2 :(得分:0)

同意代码,对吗? :-)怎么样

while True:
    backup = input
    for letter in string.ascii_lowercase: input = input.replace(letter * 2, '')
    if backup == input: break