给定未排序的字符串,例如“天文数字”。我想在范围内找到字符“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)
答案 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
。