Python 计数并删除每个子字符串

Python 计数并删除每个子字符串,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,我正在写一个程序,它计算并删除子字符串的出现。这两个操作一次完成一个 但这并不适用于所有情况: 工作正常: 不起作用: 代码如下: def count_delete(string, substring): occurrence = 0 for i in range(len(string)): if string[i:i + len(substring)] == substring: occurrence += 1 s

我正在写一个程序,它计算并删除子字符串的出现。这两个操作一次完成一个

但这并不适用于所有情况:

工作正常:

不起作用:

代码如下:

def count_delete(string, substring):
    occurrence = 0
    for i in range(len(string)):
        if string[i:i + len(substring)] == substring:
            occurrence += 1
            string = string.replace(substring, "", 1)
    return occurrence

def main():
    string = 'abbab'
    substring = 'ab'
    count = count_delete(string, substring)
    print("Occurrences:", count)

if __name__ == '__main__':
    main()
如何在所有情况下获得正确的输出

    for i in range(len(string)): ***** 1
        if string[i:i + len(substring)] == substring: ***** 3
            occurrence += 1
            string = string.replace(substring, "", 1) ***** 2
你的错误在我标记的行上

在第******2行,删除刚刚找到的子字符串。然后在******1上,你将增加i。如果substring紧跟在substring之后,您将无法检测到它,因为您的i变量已经前进了

我建议对现有代码进行以下修改:

  • 查找子字符串的所有实例并标记位置,无需修改
  • 根据上一步中标记的位置,从后面开始删除所有子字符串
  • 或者,将******3更改为while循环。

    import re
    字符串='abbcab'
    子字符串='ab'
    打印(len(re.findall(r''+子字符串,字符串)))
    #2
    打印(关于子字符串(r''+子字符串',字符串))
    #卑诗省
    #更新:看起来简单的字符串操作就可以完成这项任务。
    打印(字符串.计数(子字符串))
    打印(字符串.替换(子字符串“”)
    
    试试这个

    def count_delete(string, substring):
        '''
        >>> print(count_delete('aabbcab', 'ab'))
        (2, 'abc')
        '''
        occurrence = 0
        i = 0
        while i < len(string):
            if string[i:i + len(substring)] == substring:
                occurrence += 1
                # string = string.replace(substring, "", 1) # replaces from index 0
                string = string[:i] + string[i+len(substring):]
                # substring was removed, so we keep i on the same position
            else:
                i += 1
                # substring not found, try next position
        return occurrence, string
    

    由于您丢弃了缩减字符串,只报告出现的次数,因此有一种更简单、更快的方法:

    >>> 'abbab'.count('ab')
    2
    >>> 'abab'.count('ab')
    2
    

    此代码可能更适合您:

    def count_del(string, substring):
        occurs = 0
    
        #using the find method to increment counter
        #if -1, no substring found, if 0 or >0, substring found
        #increment counter and search to the right of substring
    
        while string.find(substring) >= 0:
            string = string[string.find(substring) + len(substring):]
    
            #truncate all strings until substring + len(substring)
            #search only items in the right of substring
    
            occurs +=1
        return occurs
    
    ========= 将我的旧代码和注释保留为本节注释中的参考

    每次进入循环时,都会减少字符串的长度。这会弄乱if语句中
    i
    的值

    如果字符串[i:i+len(子字符串)]==子字符串:

    当您第一次进入循环时,
    i
    0
    ,因此,您的if语句将转换为:

    如果字符串[0:0+2]==子字符串:

    第二次进入循环时,
    i
    为1,因此,if语句将转换为:

    如果字符串[1:1+2]==子字符串:

    我不认为这是你想做的。您仍然希望从0而不是1进行搜索

    如果您按如下方式更改代码,它将为您提供所需的结果

    def count_delete(string, substring):
        occurrence = 0
        while len(string) >= len(substring):
        #for i in range(len(string)):   replaced for loop with while
            #check the string from beginning to len of substring
            if string[:len(substring)] == substring:
                occurrence += 1
                #string = string.replace(substring, "", 1)
            #instead of removing the entire substring, 
            #you may want to check if there are more occurrences of the same
            #to do that, use the below line
    
            string = string[1:]
    
            #this will find 2 'abab' in 'abababb' instead of 1
            #if thats what you want
        return occurrence
    

    如果不返回字符串,为什么要修改它?将替换行移动到for循环的后面,并通过删除1替换所有发生的事件parameter@RichieV计数和删除必须按照问题陈述以连续的方式进行。请链接到问题陈述。@RichieV然后它将计算重叠的出现。我认为人们没有注册以下用例。案例1:字符串:aaa,模式:aa,结果:a。案例2:字符串:aba,模式aba,结果:ba。先读后删除可以工作,只要在阅读时跳过i(即,如果找到,i+=pattern.length-1),这样就不会检测到重叠的匹配,但不能使用库调用,如findAll。感谢您指出错误。我已将
    if
    更改为
    while
    循环。将上述代码用于
    ababababab
    将为您提供
    occurrence=2
    ,问题是您在
    if语句中使用了
    I
    。您应该使用
    [:len(子字符串)]
    而不是
    [i:i+len(子字符串)]
    。我没有投反对票,但希望你更正代码。此代码将不提供正确的result@JoeFerndz对于
    string=abababab
    substring=ab
    ,我得到了
    实例:3
    。请注意,根据@John的建议,我已将
    if
    更改为
    while
    。代码是OP的代码副本/粘贴,带有标记行。我没有对原始代码进行任何修改,而是将其粘贴到参考行号上,因此没有什么需要更正的。一旦OP更改了他正在运行的代码,他将不会遇到连续模式检测的问题。@John,对此感到抱歉。我不知道你指的是操作码@Saurabh,如果您尝试原始代码,
    string=abababab
    substring=ab
    将给出
    出现次数:2
    您不应该从
    i
    搜索字符串,因为您正在修剪字符串。这种逻辑是不正确的。请参阅我的答案以获取解释。@非常感谢您指出,
    .replace
    从index0中查找第一个匹配项,在这种情况下,通过在上一次迭代中删除
    子字符串形成了一个新的匹配项。您可以将
    \string=string.replace(子字符串,”,1)
    替换为
    string=string[len(子字符串):]
    它将给您相同的结果。您对问题提出了不同的解释,这也是正确的……但是,您的代码将无限循环,除非字符串是子字符串的精确倍数(例如,“abababac”/“ab”将卡在“c”上,并且永不中断)@RichieV,谢谢。我没听懂。我的不好。谢谢。修复了代码。另外,我认为如果问题仅仅是查找字符串的出现情况,最简单的方法就是进行计数。您的编辑仍然不会中断字符串
    abababababab
    substring
    b
    …我同意,但我认为此练习的目的是提高对r的认识同时循环+修改iterable@John它产生1。你为什么不试试呢?它比你的评论更难打字。
    >>> 'abbab'.count('ab')
    2
    >>> 'abab'.count('ab')
    2
    
    def count_del(string, substring):
        occurs = 0
    
        #using the find method to increment counter
        #if -1, no substring found, if 0 or >0, substring found
        #increment counter and search to the right of substring
    
        while string.find(substring) >= 0:
            string = string[string.find(substring) + len(substring):]
    
            #truncate all strings until substring + len(substring)
            #search only items in the right of substring
    
            occurs +=1
        return occurs
    
    def count_delete(string, substring):
        occurrence = 0
        while len(string) >= len(substring):
        #for i in range(len(string)):   replaced for loop with while
            #check the string from beginning to len of substring
            if string[:len(substring)] == substring:
                occurrence += 1
                #string = string.replace(substring, "", 1)
            #instead of removing the entire substring, 
            #you may want to check if there are more occurrences of the same
            #to do that, use the below line
    
            string = string[1:]
    
            #this will find 2 'abab' in 'abababb' instead of 1
            #if thats what you want
        return occurrence