例如:
'hello'.count('e')
这是O(n)吗?我猜它的工作方式是它扫描'hello'
并在每次看到字母'e'
时递增计数器。我如何在不猜测的情况下知道这一点?我尝试阅读源代码here,但却发现了这个问题:
def count(s, *args):
"""count(s, sub[, start[,end]]) -> int
Return the number of occurrences of substring sub in string
s[start:end]. Optional arguments start and end are
interpreted as in slice notation.
"""
return s.count(*args)
我在哪里可以阅读s.count(*args)
中执行的内容?
编辑:我理解*args
在Python函数的上下文中的作用。
答案 0 :(得分:7)
str.count
在stringobject.c
文件的本机代码中实现,该文件委托给stringlib_count
或PyUnicode_Count
,后者本身再次委托给stringlib_count
。 stringlib_count
最终使用fastsearch
来搜索字符串中子字符串的出现次数并对其进行计数。
对于单字符字符串(例如您的'e'
),它会与以下代码路径短路:
for (i = 0; i < n; i++)
if (s[i] == p[0]) {
count++;
if (count == maxcount)
return maxcount;
}
return count;
所以是的,这就像你假设对字符串序列的简单迭代并计算子字符串的出现一样。
对于长于单个字符的搜索字符串,由于处理重叠等原因,它会变得有点复杂,并且逻辑被深埋在fastsearch
实现中。但它基本上是相同的:通过字符串进行线性搜索。
所以是的,str.count
处于线性时间,O(n)。如果你考虑一下,它就会很有意义:为了知道子串出现在字符串中的频率,你需要查看相同长度的每个可能的子串。因此,对于子字符串长度为1,您必须查看字符串中的每个字符,从而为您提供线性复杂性。
顺便说一下。有关基础快速搜索算法的更多信息,请参阅this article on effbot.org。
对于只有一个Unicode字符串类型的Python 3,实现的链接是:unicode_count
使用stringlib_count
使用fastsearch
。
答案 1 :(得分:1)
很多python的库代码都是用C语言编写的。您正在寻找的代码在这里:
http://svn.python.org/view/python/trunk/Objects/stringobject.c?view=markup
map( { (.name): del(.name) } ) | add
答案 2 :(得分:1)
如果你追求@ AJNeufeld的回答,你最终会遇到这个链接,它解释了(然后)新的查找逻辑是如何工作的。它是多种字符串搜索方法的组合,旨在从一些逻辑中受益,但避免了搜索的前期表设置成本:http://effbot.org/zone/stringlib.htm
Boyer-Moore是一种着名的字符串搜索算法。 BM-Horspool和BM-Sunday是以某种方式改进原版的变种。谷歌会发现你比你想知道的更多。