如何在字符串的特定范围内有效地计算给定字符的出现次数?

时间:2017-04-18 08:08:01

标签: python arrays string algorithm

给定未排序的字符串,例如“天文数字”。我想在范围内找到字符“o”的出现次数:[1,3]。所以,在这种情况下,答案是1。

但是,我的方法具有复杂度O(N ^ 2)。我的方法的问题是复制数组需要O(N)时间。因此,我正在寻找另一种更有效的方法。空间复杂性对我来说无关紧要。因为我正在学习字符串处理算法,所以如果我能够自己实现这个算法会更好。

任何帮助都将不胜感激。

我的方法。

tmp = [0] * 26  # 26 alphabet
occurrences_table = []
tmp[ord(a_string[0])] += 1
occurrences_table.append(tmp)
for i in range(1, len(a_string)):
    temp = occurrences_table[i - 1]
    temp[ord(a_string[i])] += 1
    occurrences_table.append(temp)

3 个答案:

答案 0 :(得分:2)

由于您不想使用counter并希望自己实现它,因此可以使用词典来整理和加快您的代码。

a_string = "googol"
my_counter = {}
for c in a_string[:2]:
    my_counter[c] = my_counter.get(c, 0) + 1

会给你:

{'o': 1, 'g': 1}

要进一步解释它a_string[:2]会使字符串中的字符达到索引2('google'[:2] = 'go'),for c in a_string[:2]:遍历这2个字符。

在下一行中,my_counter.get(c, 0) + 1尝试获取键'c'(字符串中的单个字符)的字典值,如果存在则返回其值,如果不是则返回0并且任一方式添加增量值返回字典。

修改

由于for循环,复杂性应该只是O(n),因为dictionary.get()的复杂性是不变的。

我已经测量了它,对于像你这样的非常小的字符串,这种方法比Collections.Counter快8到10倍,但对于非常大的字符串,它的速度要慢2-3倍。

答案 1 :(得分:1)

您可以使用Counter

from collections import Counter
a_string = "googol"
occurrences = Counter(a_string[0:2])

导致

Counter({'o': 1, 'g': 1})

请注意,数组切片适用于字符串。

答案 2 :(得分:0)

如果您可以使用标准库:

>>> from itertools import islice
>>> from collections import Counter
>>> Counter(islice('googol', 1, 3))
Counter({'o': 2})
>>> Counter(islice('googol', 0, 2))
Counter({'g': 1, 'o': 1})

islice避免使用临时列表。)

如果您想手动执行此操作:

>>> s = 'googol'
>>> counter = dict()
>>> for i in range(0, 2):
...     if s[i] not in counter:
...         counter[s[i]] = 1
...     else:
...         counter[s[i]] += 1
... 
>>> counter
{'g': 1, 'o': 1}

重点是:使用dict