用于递归删除偶数计数的相邻重复字母的代码

时间:2018-10-13 14:04:36

标签: python python-3.x recursion

最近我被要求编写代码以递归的方式在实时编码测试中删除偶数的相邻字母,当时我无法编写代码,此后我尽了最大努力。逻辑和代码?

例如cbbbaaaabbbccc => cbbbbbbccc => cccc =>空字符串

例如aabbc => bbc => c

例如abbbccc => abbbccc-因为没有字母重复偶数

编辑-我根据罗里的建议编辑了代码,但仍然不明白为什么在字符串变为空后为什么要进行递归调用而不是跳出循环

str = "cbbbaaaabbbccc"   


def remUtil(str):
i = 0
ind = 0
while i < (len(str)-1):
    j = 0
    if str[i] == str[i + 1]:
        j = i
        ind = i
        count = 0
        while j < len(str)-1 and str[j] == str[j + 1]:
            count = count + 1
            j = j + 1
            i = i + 1
        # if the no. of comparisons are odd then even letters compared
        if count % 2 != 0:
            str = str[:(ind)] + str[(ind + count) + 1:]
            #print(str)
            remUtil(str)


    else:
        i = i + 1

3 个答案:

答案 0 :(得分:2)

一个简短的版本,避免了对索引的操纵:

def rm_even_duplicates(s):
    ls = list(s) + [None]
    tmp = [ls[0]]
    out = []
    for c in ls[1:]:
        if c != tmp[0]:
            if len(tmp) % 2 == 1:
                out.extend(tmp)
            tmp = []
        tmp.append(c)
    # The recursive part, if you want to do it that way;
    # that could as well have been a while loop
    if len(out) == len(s):
        return ''.join(out)
    else:
        return rm_even_duplicates(out)

一些示例和您的测试用例:

print(rm_even_duplicates('aaabbcdddd'))
# aaac
print(rm_even_duplicates('aaabbccaaadda'))
# aaaaaaa

assert rm_even_duplicates('cbbbaaaabbbccc') == ''
assert rm_even_duplicates('aabbc') == 'c'
assert rm_even_duplicates('abbbccc') == 'abbbccc'

答案 1 :(得分:1)

代码中存在一些效率低下的问题,但是由于无法足够小心地防止索引超出字符串末尾而导致的错误。

首先,您的行while i < (len(str)):防止i过大。但是,两行之后,您使用的i + 1可能太大。因此,您不仅希望将i保留在字符串中,还希望防止其指向字符串的末尾。您可以通过将行更改为

while i < len(str) - 1:

第二,您在j上的循环不会阻止jj + 1超出字符串末尾运行。将行while str[j] == str[j + 1]:替换为

while j < len(str) - 1 and str[j] == str[j + 1]:

我还删除了第二行中的缩进,这在Python中非常重要。有了这些更改,您的代码就可以正常工作了。您可以通过其他方式改进代码,但是在我提交的示例中,代码可以得到正确的结果。


您的代码不返回任何内容,仅显示字符串的中间值和最终值。如果要返回最终值并且不打印在字符串中(例程的通常目标是这样),请删除print行,将已更改的str值存储回{{1} },并将行str放在函数的末尾。以下是经过所有这些修改的代码。我不太愿意这样做,但是这段代码对您的代码所做的更改很小,但是却给出了正确的结果。

return str

答案 2 :(得分:1)

我试图永远不要错过在序列计数问题上抛出itertools groupby的机会:

from itertools import groupby

def remUtil(str_or_list):
    characters = []
    length = 0

    for _, group in groupby(str_or_list):
        sub_characters = list(group)
        sub_length = len(sub_characters)

        if sub_length % 2:
            characters.extend(sub_characters)
            length += sub_length

    if length == len(str_or_list):
        return str_or_list if isinstance(str_or_list, str) else ''.join(str_or_list)

    return remUtil(characters)


# Borrowing @ThierryLathuille's test cases (+1)

print(remUtil('aaabbcdddd'))
print(remUtil('aaabbccaaadda'))

assert remUtil('cbbbaaaabbbccc') == ''
assert remUtil('aabbc') == 'c'
assert remUtil('abbbccc') == 'abbbccc'