字符串对比
好久沒更(水)博客了,今天有空了來更(水)一下
一
按照我的理解就是 判斷兩個字符串是否99% 相似,兩個字符串只能有一個字符的不同
1.1逐個匹配
我第一想法是逐個字符進行匹配,然后記錄兩個字符的不同字符數,然后進行判斷, 如:
def no_equal(str1, str2):nums = 0# 記錄不同字符列表ls_list = []# 以str1為主進行匹配,所有str1為最長的那個字符串if len(str1) < len(str2):str1, str2 = str2, str1count = 1while 1:print("循環{}次".format(count))count += 1if nums >= len(str1):breaktry:# 如果循環到兩個字符串的同一個下標值不同的時候,# 將這個不同值從str1字符串中切割出來,構造出新的str1字符串if str1[nums] != str2[nums]:# 如果這個下標不為0的時候,就進行正常的切割if nums > 0:ls_list.append(str1[nums])str1 = str1[0:nums] + str1[nums + 1:]else:# 下標為0,直接切割str1 = str1[1:]else:# 如果兩個字符串相同的下標的數據一樣時,nums下標+1nums += 1except:# 有種情況是str1切了多次,長度和str2不匹配了,就來判斷兩個字符串最后一位是否相同,并結束循環if str1[-1] != str2[-1]:ls_list.append(str1[-1])breakif len(ls_list) > 1:return Falsereturn Truedef equal(str1, str2):nums = 0# 臨時列表,記錄兩個字符串中不同的字符ls_list = []count = 1while nums < len(str1):print("循環{}次".format(count))count += 1# 如果循環匹配到字符串相同的下標的字符不一樣的時候, 就用臨時列表記錄下來if str1[nums] != str2[nums]:ls_list.append(str1[nums])nums += 1# 如果不同字符數量超過了2位,則這兩個字符返回Falseif len(ls_list) > 1:return Falsereturn Truedef isStringAlike(str1, str2):# 如果兩個單詞字符數相等,調用equal 函數進行操作if len(str1) == len(str2):return equal(str1, str2)# 如果兩個字符串的長度差在1之間,調用no_equal 函數進行判斷elif len(str1) + 1 == len(str2) or len(str1) - 1 == len(str2):return no_equal(str1, str2)# 字符長度不合適return Falseprint(isStringAlike("snapchat", "snap1chat"))這種做法比較耗時間,循環次數的是最長字符串的長度
1.2中間分隔
第二種方法就比第一種快多了, 主要是將字符串平方后再對比,每次循環都可以減少 1/2長度
def no_equal(str1, str2):# 這里str2是最長的字符串,一最短的字符串 str1為對比基礎nums = 1while len(str1) > 1:print("循環{}次".format(nums))nums += 1# 切割下標數end_nums = len(str1[0:]) // 2# print(end_nums)t_f = 0# 判斷兩個字符串前半部分的字符串是否相同if str1[0:end_nums] != str2[0:end_nums]:# 如果前半部分的字符串不相同,并且長的str1往后移一位和str2的后半部分也不相同的時候# 就說明這兩個字符串有兩處不相同,直接可以返回False了if str1[end_nums:] != str2[end_nums + 1:]:return False# 否則將相同的部分切除,得到不同的前半部分str1, str2 = str1[0:end_nums], str2[0:end_nums+1]t_f = 1if t_f == 0:# 切割對比出來的不相同的前半部分str1, str2 = str1[end_nums:], str2[end_nums:]# print(str1, str2)# 當切割到最后只剩一位字符的時候, 并且str1的最后一個字符和str2第一個或第二個字符相同的時候,可以返回Falseif len(str1) == 1 and (str1 == str2[0] or str1 == str2[-1]):return Truereturn Falsedef equal(str1, str2):nums = 1while len(str1) > 1:lists = []print("循環{}次".format(nums))nums += 1# 獲取字符串的中間的下標end_nums = len(str1) // 2t_f = 1# 如果兩個字符串前半部分不相同,則添加到判斷列表中if str1[0:end_nums] != str2[0:end_nums]:lists.append(str1[0:end_nums])# 如果兩個字符串后半部分也不相同,也添加到判斷列表中if str1[end_nums:] != str2[end_nums:]:lists.append(str1[end_nums:])t_f = 2# 如果判斷列表中的數據大于1,這代表這兩個字符串有最少兩處不相同,直接可以結束循環了if len(lists) > 1:print(lists)return False# 通過上面兩個if,判斷兩個字符串中是哪里(前半部分or后半部分)不相同,# 將相同的部分切除if t_f == 1:str1, str2 = str1[0:end_nums], str2[0:end_nums]else:str1, str2 = str1[end_nums:], str2[end_nums:]# 當兩個字符串切割到最后一個時沒有返回false時, 就不要再循環對比了,可以直接返回true了return Truedef isStringAlike(str1, str2):# 如果兩個單詞字符數相等,調用equal 函數進行操作if len(str1) == len(str2):return equal(str1, str2)elif len(str1) + 1 == len(str2) or len(str1) - 1 == len(str2):# 如果兩個字符串的長度差在1之間,調用no_equal 函數進行判斷if len(str1) > len(str2):str1, str2 = str2, str1return no_equal(str1, str2)return False# print(isStringAlike("snapchat", "sn11chat")) print(isStringAlike("snapchat", "snapchat"))直觀的對比
可以看到,第二次的方法比第一次的要好很多
總結
- 上一篇: Pgpool安装部署(亲测可用)
- 下一篇: DS1820温度测量程序