个人学习记录,如有错误欢迎指正。持续更新中…
变位词判断
所谓“变位词”就是指两个数之间存在组成字母的重新排列关系。
假设:参与判断的两个词仅由小写字母组成,且长度相同。
逐字检查
思路:
将词1中的字符逐个到词二中检查是否存在,存在就打勾标记。若每个字符都能找到,则两个词是变位词;只有一个字符找不到,就不是变位词。
将词2的对应字符设为None,以此来实现打勾标记。
#逐字检查法
def anagram_solution1(s1, s2):
alist = list(s2) # 将s2转换为字符串形式,方便其实现打勾操作
pos1 = 0
still_ok = True
while pos1 < len(s1) and still_ok: # 遍历s1的每个字符
pos2 = 0
found = False
while pos2 < len(alist) and not found: # 在s2中逐个对比
if s1[pos1] == alist[pos2]:
found = True
else:
pos2 += 1
if found:
alist[pos2] = None # 找到就打勾
else:
still_ok = False # 1个字符找不到就为失败
pos1 += 1
return still_ok
print(anagram_solution1('python', 'typhon'))
数量级为 O ( n 2 ) O(n^2) O(n2).
讨论区提到的两个问题:
1.考虑字符串不一样长时,如abc与abcccccc
2.moon与mont返回True,程序还需要一第二个列表为参照物再循环一次
排序比较
思路:
将两个字符串都按照字母顺序排好序,再逐个字符对比。若相同则是变位词,有任何不同则不是。
# 排序比较法
def anagram_solution2(s1, s2):
list1 = list(s1)
list2 = list(s2)
list1.sort()
list2.sort()
pos = 0
matches = True
while pos < len(s1) and matches:
if list1[pos] == list2[pos]: # 若相同位置上元素相同,则检查下一个位置
pos += 1
else:
matches = False # 若不同,则返回错误
return matches
print(anagram_solution2('python', 'typhon'))
其实我觉得不用这么麻烦,直接比较排序后的两个列表是否相同就行,如下:(补充:可能一个一个比较比较省时间,只要一个不对就直接返回错误,只是我的猜测)(再补充:实验证明直接return list1== list2比较省时间)
# 排序比较法
def anagram_solution2(s1, s2):
list1 = list(s1)
list2 = list(s2)
list1.sort()
list2.sort()
if list1 == list2: # 直接比较 (此步直接return list1== list2就可)
matches = True
else:
matches = False # 若不同,则返回错误
return matches
print(anagram_solution2('python', 'yyphon'))
数量级不是 O ( n ) O(n) O(n),使用排序算法的运行时间数量级差不多是 O ( n 2 ) O(n^2) O(n2)或 n ∗ log n n*\log n n∗logn. 故本算法的运行时间数量级等于排序过程的数量级 n ∗ log n n*\log n n∗logn.
暴力法
思路:穷尽所有可能的组合(太暴力!一般不考虑)
计数比较
思路:
对比两个词中每个字母出现的次数,如果26个字幕出现的次数都相同,则两个字符串就一定是变位词。
具体做法:
为每个词设置一个26位的计数器,先检查每个词,在计数器中设定好每个字母出现的次数。计数完成后,在进行比较。
# 计数比较法
def anagram_solution4(s1, s2):
c1 = [0] * 26 # 生成一个有26个0元素的列表
c2 = [0] * 26
for i in range(len(s1)):
pos = ord(s1[i]) - ord('a') # 此字符在列表的第几位,从0开始计位
c1[pos] += 1 # 在此计数位上+1
for i in range(len(s2)):
pos = ord(s2[i]) - ord('a')
c2[pos] += 1
return c1 == c2
print(anagram_solution4('python', 'typhonn'))
此办法可以避免方法1最后提到的两个问题。
数量级为 O ( n ) O(n) O(n).
但是需要牺牲更多的储存空间!