什么更有效?使用.replace()或将字符串传递给列表

时间:2017-07-06 17:19:12

标签: python string performance

从CodeFights解决以下问题:

  

给定两个字符串,找到它们之间的公共字符数。   对于s1 =“aabcc”和s2 =“adcaa”,输出应为   commonCharacterCount(s1,s2)= 3。

     

字符串有3个常用字符 - 2“a”和1“c”。

我接近它的方式,每当我考虑到一封信时,我都想取消它,以免再次计算它。我知道字符串是不可变的,即使使用诸如.replace()之类的方法(replace()方法返回字符串的副本,也没有更改实际字符串)。

为了改变所说的string我在开始时倾向于做的只是将其传递给list(mystring)的列表,然后改变它。

问题 ...以下哪项更有效?考虑到选项B一遍又一遍地完成,最坏的情况是字符串相等并且匹配匹配。同时选项A发生一次。

选项A)

list(mystring) 

选项B)

mystring = mystring.replace(letterThatMatches, "")

1 个答案:

答案 0 :(得分:7)

在您找到的每个元素的字符串上调用replace的想法根本不是一个好主意:它需要 O(n)来执行此操作。如果对另一个字符串中的每个字符执行此操作,将生成 O(m×n)算法,其中 m 第一个字符串的字符数,并且 n 第二个字符串中的字符数。

您可以简单地使用两个Counter,然后计算两者中的最小值,然后计算计数的总和。像:

from collections import Counter

def common_chars(s1,s2):
    c1 = Counter(s1) # count for every character in s1, the amount
    c2 = Counter(s2) # count for every character in s2, the amount
    c3 = c1 & c2 # produce the minimum of each character
    return sum(c3.values()) # sum up the resulting counts

或作为单行

def common_chars(s1,s2):
    return sum((Counter(s1) & Counter(s2)).values())

如果字典查找可以在 O(1)中完成(通常适用于普通情况),这是一个 O(m + n)算法:然后分别在 O(m) O(n)中进行计数,并计算不同字符数(最多 O)的最小运行次数( max(m,n))。最后取总和再次是 O(max(m,n))操作。

对于样本输入,结果如下:

>>> common_chars("aabcc","adcaa")
3