![](/img/trans.png)
[英]given two sentences S1,S2 ; task is to find Words in S1 but not in S2
[英]Why is Sort(s1)==Sort(s2) better to use than Counter(s1)==Counter(s2)
这是否被视为检查两个字符串是否彼此置换的有效方法? 改用两个字典有什么区别? Counter更适合python吗?
我想我应该澄清一下,我发表这条评论的原因是这样的评论: 检查两个无序列表是否相等,提到使用sort(s1)== sort(s2)检查两个字符串是否相同更有效。这是o(nlog(n)),您将认为Counter的运行时间更好。
在您提到的另一个问题中, JF Sebastian认为在几乎所有情况下使用sort
都会比使用Counter
更快,但他明智地指出,如果您真的很在意,您应该进行以下测量:“在实践中,它可能总是比collections.Counter()
更快。 collections.Counter()
(尽管对于.sort()
渐近O(n)
时间比O(n*log(n))
好。)请测量它,如果它很重要。”
如下所示。 重点:
列表大小最多约为10^6
, sort
速度更快。
随着列表大小的增加,这种优势逐渐减少。
这些实验使用具有许多离散值的列表。 如果列表中重复值的百分比较高,则基准可能会有所不同。
这些测量表明,创建Counter
的开销通常比仅对数据进行排序的开销要大。 考虑这种情况的一种方法是查看Counter
创建相对于sort
方法的log(n)
部分的开销。 直到n
变得相当大时, Counter
数据结构的算法优势才开始得到足够的回报以证明该开销是合理的。
但是请记住 :对于小数据量,速度优势可能无关紧要-除非您要大容量重复操作。 鉴于此,从代码设计的角度来看,对于大多数用例,“算法正确”的方法(使用Counter
)可能仍然更好-因为如果数据很大,则速度更快,而如果数据很小,则速度足够快。
编码:
import timeit, sys, random
from collections import Counter
def prep():
random.shuffle(xs)
random.shuffle(ys)
def use_counter():
prep()
return Counter(xs) == Counter(ys)
def use_sort():
prep()
xs.sort()
ys.sort()
return xs == ys
experiments = [
(3, 10, 100000),
(3, 100, 10000),
(3, 1000, 1000),
(3, 10000, 100),
(3, 100000, 10),
(3, 1000000, 1),
(1, 10000000, 1),
]
for e in experiments:
repeat, list_size, timeit_n = e
xs = list(range(list_size))
ys = list(range(list_size))
r1 = timeit.repeat(use_counter, repeat = repeat, number = timeit_n)
r2 = timeit.repeat(use_sort, repeat = repeat, number = timeit_n)
print
print e
print 'total ', sum(r1), sum(r2)
print 'm1/m2 ', min(r1) / min(r2)
输出示例(比率> 1表示Counter
变慢):
(3, 10, 100000)
total 5.06751918793 2.15432405472
m1/m2 2.34850470872
(3, 100, 10000)
total 3.16299915314 2.06651735306
m1/m2 1.52879303981
(3, 1000, 1000)
total 3.017786026 2.42989587784
m1/m2 1.24086325316
(3, 10000, 100)
total 3.06426525116 2.74061489105
m1/m2 1.11802891855
(3, 100000, 10)
total 3.66198205948 3.35467290878
m1/m2 1.1028159291
(3, 1000000, 1)
total 5.19361901283 5.08777713776
m1/m2 1.03125948765
(1, 10000000, 1)
total 20.0118789673 24.6061840057
m1/m2 0.813286569044
它是O(n),所以理论上很有效。 Counter
是字典的子类,因此唯一的区别是您必须使用Python来构建字典,而不是让Counter
类(被称为“高性能”,因此我假设是用C实现)来做到这一点。 两者都是相同的big-O,但Counter
会更快。
这是一个不同的big-O,但是对两个字符串进行排序实际上比我的系统上对Counter字符串不足的Counter
快大约四倍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.