我正在学习算法分析(python 2.7.6)。我正在读一本书(用算法和数据结构解决问题),其中Python是用于实现的语言。在第2章中,作者以非常清晰易懂的方式介绍了算法分析,并使用anagram检测程序作为模板来比较不同的运行时实现(quadratics,log linear,linear)。在线性且最有效的实现中,代码如下(我添加的注释):
def anagram_test2(s1,s2):
""" Checks if two strings are anagrams of each other
Runs with O(n) linear complexity """
if (not s1) or (not s2):
raise TypeError, "Invalid input: input must be string"
return None
# Initialize two lists of counters
c1 = [0] * 26
c2 = [0] * 26
# Iterate over each string
# When a char is encountered,
# increment the counter at
# its correspoding position
for i in range(len(s1)):
pos = ord(s1[i]) - ord("a")
c1[pos] += 1
for i in range(len(s2)):
pos = ord(s2[i]) - ord("a")
c2[pos] += 1
j = 0
hit = True
while j < 26 and hit:
if c1[j] == c2[j]:
j += 1
else:
hit = False
return hit
我的问题是: 两个for循环之后的代码块是否可以用更简单的代码替换:
if c1 == c2:
return True
else:
return False
return
哪里不需要迭代(而不是使用while语句)?使用第一种方法与第二种方法有一些计算/程序化原因吗?我在各种字符串组合上运行此版本,它的工作方式完全相同。
还有一个更普遍的问题: 作者类暗示嵌套迭代导致二次运行时,而非嵌套迭代导致线性/对数/对数线性运行时。是否有一套独特的规则来确定算法的运行时间?例如,如果没有嵌套迭代的程序,如何区分线性/对数线性/对数算法?在上面发布的示例之前的示例中,作者使用了排序和比较实现,其中没有嵌套循环,但承认sort方法有自己的成本,可以是log linear或quadratic。
答案 0 :(得分:1)
在python中你可以做c1 == c2
,但是其他语言需要一个循环,这就是作者试图展示的内容。
在python中,无论如何,单行代码对每个索引执行隐式for循环以检查是否相等。
答案 1 :(得分:0)
是的,所有这些代码都检查两个数组是否相等。要做到这一点,你可以做return c1 == c2
是否有一套独特的规则用于确定算法的运行时间 确定算法的运行时是一个复杂的过程,但可能有几个快捷方式。一些快捷方式是:
k
嵌套循环从常量到n
递增一个常量将在O(n^k)
n
的循环,乘以常量将在O(log(n))
P.S。与您的问题无关,但整个功能只能用counter代替。
from collections import Counter
def isAnagram(s1, s2):
return Counter(s1) == Counter(s2)
答案 2 :(得分:0)
看起来作者试图用O(1)操作来拼出算法(这在尝试计算整体运行时复杂度时是有意义的。)
c1 == c2
(其中c1和c2是列表)隐藏了相当多的复杂性;它实际上更像len(c1) == len(c2) and all(ch1 == ch2 for ch1,ch2 in zip(c1, c2))
。他展示了比较中涉及的基本操作。