将words.txt 转换成一个列表序列,对单词进行逐个遍历,如果存在反向对s+=1;所得结果/2即为反向对的个数
import time fp = open('words.txt', 'r') a = fp.read().split('\n') t = len(a) s = i = 0 start = time.time() while i < t: if (a[i])[::-1] in a and (a[i])[::-1] != a[i]: s += 1 print(a[i]) i += 1 print s/2 print time.time()-start
运行结果为:
397
175.286000013
效率是很低的,考虑在遍历每个单词时,如果存在反向,在word列表中删除这个单词和它的反向单词,若不存在反向对则删除这个单词。代码如下:
start = time.time() while i < t: if (a[i])[::-1] in a and (a[i])[::-1] != a[i]: s += 1 print(a[i]) print((a[i])[::-1]) a.remove((a[i])[::-1]) a.remove(a[i]) a.remove(a[i]) t = len(a) i += 1 print time.time()-start print s
运行结果为:
289
89.25
在时间效率上有将近一倍的提升,但是结果是不正确的。查阅资料发现:
问题出现for in 和 remove 方法上:
for in循环是通过list中的下标有顺序的进行循环输出,这一点没有问题,循环一次下标就加一,以此类推。
remove方法呢?这个是问题的关键,它是怎么操作的呢?网上给的解答是删除第一次出现的该元素。也就是说它会按照元素进行查询,遇到的第一个匹配的就将其删除。问题是remove删除完元素以后list将会怎样。这个是问题的关键。测试:
>>> b=['1','2']
>>> b.remove('1')
>>> print b
['2']
>>> print b[0]
2
如果对list 使用remove方法,删除的元素位置会被后面的元素填补上。所以每次从让i恒等于0,检测a[0],
代码修改:
注释掉i+=1;
删除元素后直接从a[0]开始匹配,结果为:
397
89.6889998913
结果正确时间有将近一倍的提升