我知道这段代码的效率不是最优的(特别是巨大的输入),而且我知道有一种方法可以改变这种算法来处理其他数据类型,而不仅仅是字符串中的重复(显然那里只搜索很多字符。)
有什么方法可以提高效率吗?
我尝试使用字典并且该功能一直在返回' none'所以我尝试了一个列表,事情很顺利。
提前感谢任何可以帮助我的人!
def find_repeater(string):
my_list = []
my_list.append(string[0])
for i in range (1, len(string)):
if string[i] in my_list:
print 'repetition found'
return (string[i])
else:
my_list.append(string[i])
print find_repeater('abca')
现在使用字典....(它不断打印到控制台没有'
)def find_repeater(string):
my_dict = {}
my_dict[0] = string[0]
for i in range (1, len(string)):
if string[i] in my_dict:
print 'repetition found'
return string[i]
else:
my_dict[i] = string[i]
print find_repeater('abca')
答案 0 :(得分:10)
由于这是一个性能问题,让我们来做一些时间:
def test_set(xs):
seen = set() # O(1) lookups
for x in xs:
if x not in seen:
seen.add(x)
else:
return x
import collections
def test_counter(xs):
freq = collections.Counter(xs)
for k in freq:
if freq[k] > 1:
return k
def test_dict(xs):
d = {}
for x in xs:
if x in d:
return x
d[x] = 1
def test_sort(xs):
ys = sorted(xs)
for n in range(1, len(xs)):
if ys[n] == ys[n-1]:
return ys[n]
##
import sys, timeit
print (sys.version + "\n")
xs = list(range(10000)) + [999]
fns = [p for name, p in globals().items() if name.startswith('test')]
for fn in fns:
assert fn(xs) == 999
print ('%50s %.5f' % (fn, timeit.timeit(lambda: fn(xs), number=100)))
我正在测试一个整数列表而不是一个字符串(因为使用一个字符串,你不能获得超过256个循环)。我机器上的结果如下所示:
3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
<function test_set at 0x1020f7380> 0.19265
<function test_dict at 0x1020f7490> 0.12725
<function test_sort at 0x1020f7518> 0.04683
<function test_counter at 0x1020f7408> 0.92485
所以排序方法似乎是胜利者。我想这是因为它不浪费时间创建哈希并分配字典/集结构。此外,如果您不关心要更改的源列表,则可以执行xs.sort()
而不是ys = sorted(xs)
,这样可以减少内存占用。
另一方面,如果重复的项目更有可能在输入的开头发生(如xs = 'abcdef' * 10000
),set
方法将表现最佳,因为它不像{{ 1}}或sort
,一旦找到重复就立即返回,并且不需要预处理整个列表。如果您需要第一个重复元素,还应该使用Counter
,而不仅仅是其中之一。
set
是一个很好的工具,但它并不是为性能而设计的,所以如果你真的需要处理“巨大的输入”,那就去设置(如果它们适合内存)或者如果它们不适合则进行合并。
答案 1 :(得分:4)
您可以使用collections
查找重复字符:
import collections
freq = collections.Counter("abcda")
for k in freq:
if freq[k] > 1:
print k # prints "a"
break
如果您只想查找是否有重复(没有找到重复的字符):
letters = list("abcda")
no_rep = set(letters)
print len(letters) > len(no_rep) # prints 'True' when there are repeating characters
答案 2 :(得分:2)
def find_repeater(mystr):
seen = set() # O(1) lookups
for char in mystr:
if char not in seen:
seen.add(char)
else:
print('repetition found')
return char
答案 3 :(得分:1)
在这里,您可以使用字典:
def find_repeater(string):
my_list = {}
my_list[string[0]] = 1
for i in range (1, len(string)):
if string[i] in my_list.keys():
print 'repetition found'
return (string[i])
else:
my_list[string[i]] = 1
print find_repeater('abca')
就个人而言,我会在这里使用一套:
def find_repeater(string):
my_list = set()
my_list.add(string[0])
for i in range (1, len(string)):
if string[i] in my_list:
print 'repetition found'
return (string[i])
else:
my_list.add(string[i])
print find_repeater('abca')
答案 4 :(得分:0)
这应该有用。
def return_dupe(string):
d = {}
[d.update({k:2}) if k in d else d.update({k:1}) for k in string]
return [key for key in d if d[key] > 1]
答案 5 :(得分:0)
另一种方法可以简单:
def repeting_count(text):
working_text = str(text.lower())
dup = []
for char in working_text:
if working_text.count(char) > 1:
dup.append(char)
else:
pass
for num in dup:
while dup.count(num) > 1:
dup.remove(num)
答案 6 :(得分:0)
def rec_char(s):
buf={}
for c in s:
try:
print(buf[c],end=", ")
except:
buf[c]=c
rec_char("ABCAB")
时间复杂度为O(n)的python3中的此函数将打印出现多次的字符。