Python 递归删除偶数相邻重复字母的代码

Python 递归删除偶数相邻重复字母的代码,python,python-3.x,recursion,Python,Python 3.x,Recursion,最近,在一次实时编码测试中,我被要求编写代码,以递归方式删除偶数的相邻字母。当时我无法编写代码。此后我尽了最大努力。我的逻辑和代码有什么问题 例如cbbbaaaabbbccc=>cbbbbccc=>cccc=>empty string 例如aabbc=>bbc=>c 例如abbbccc=>abbbccc-因为没有字母以偶数重复 编辑-我根据Rory的建议编辑了代码,但仍然不明白为什么字符串变空后,它会进入递归调用,而不仅仅是退出循环 str = "cbbbaaaabbbccc" def

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

例如cbbbaaaabbbccc=>cbbbbccc=>cccc=>empty string

例如aabbc=>bbc=>c

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

编辑-我根据Rory的建议编辑了代码,但仍然不明白为什么字符串变空后,它会进入递归调用,而不仅仅是退出循环

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
str=“cbbbaaaabbbccc”
def remUtil(str):
i=0
ind=0
而我<(len(str)-1):
j=0
如果str[i]==str[i+1]:
j=i
ind=i
计数=0
而j
您的代码中有一些效率低下的地方,但您所遇到的错误是由于在防止索引超出字符串末尾时不够小心

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

while i < len(str) - 1:
我还删除了第二行中的一个错误缩进,这在Python中非常重要。通过这些更改,您的代码似乎可以正常工作。您可以用其他方式改进代码,但代码在我给出的示例中得到了正确的结果


代码不返回任何内容,只打印字符串的中间值和最终值。如果要返回最终值而不在字符串中打印(这是类似例程的常见目标),请删除
print
行,将更改后的
str
值存储回
str
,并将该行
return str
放在函数末尾。下面是经过所有这些修改的代码。我不太愿意这样做,但是这段代码对您的代码做了最小的更改,但给出了正确的结果

#str = "cbbbaaaabbbccc"   
str = "aabbd"     

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:]
                str = remUtil(str)
        else:
            i = i + 1
    return str

print(remUtil(str))
#str=“cbbbaaaabbbccc”
str=“aabbd”
def remUtil(str):
i=0
ind=0
而i
您的代码中有一些效率低下的地方,但您所遇到的错误是由于在防止索引超出字符串末尾时不够小心

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

while i < len(str) - 1:
我还删除了第二行中的一个错误缩进,这在Python中非常重要。通过这些更改,您的代码似乎可以正常工作。您可以用其他方式改进代码,但代码在我给出的示例中得到了正确的结果


代码不返回任何内容,只打印字符串的中间值和最终值。如果要返回最终值而不在字符串中打印(这是类似例程的常见目标),请删除
print
行,将更改后的
str
值存储回
str
,并将该行
return str
放在函数末尾。下面是经过所有这些修改的代码。我不太愿意这样做,但是这段代码对您的代码做了最小的更改,但给出了正确的结果

#str = "cbbbaaaabbbccc"   
str = "aabbd"     

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:]
                str = remUtil(str)
        else:
            i = i + 1
    return str

print(remUtil(str))
#str=“cbbbaaaabbbccc”
str=“aabbd”
def remUtil(str):
i=0
ind=0
而i
一个较短的版本,避免了对索引的操纵:

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'

较短的版本,避免操纵指数:

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'

我尽量不错过在序列计数问题上抛出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'

我尽量不错过在序列计数问题上抛出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'

@RoryDaulton,我举了一些例子。你的例子稍微改进了问题说明,但没有回答我所有的问题。如果一个字母位于多个位置(例如
'aaba'
'aaaba'
),情况如何?此外,递归实际上是必需的吗?在我看来,与