此篇文章的replace实现了字符串类的多次匹配,但依然有些不足。
因为python字符串对象为不变对象,所以replace方法并不修改原先的字符串,而是返回修改后的字符串。
而此字符串对象时用单链表结构实现的,在实现replace时改变了字符串对象本身的结构。
1 前面省略,见上一篇。。。。
2
3 #单链表字符串类
4 class string(single_list):
5 def __init__(self, value):
6 self.value = str(value)
7 single_list.__init__(self)
8 for i in range(len(self.value)-1,-1,-1):
9 self.prepend(self.value[i])
10
11 def length(self):
12 return self._num
13
14 #获取字符串对象值的列表,方便下面使用
15 def get_value_list(self):
16 l = []
17 p = self._head
18 while p:
19 l.append(p.elem)
20 p = p.next
21 return l
22
23 def printall(self):
24 p = self._head
25 print("字符串结构:",end="")
26 while p:
27 print(p.elem, end="")
28 if p.next:
29 print("-->", end="")
30 p = p.next
31 print("")
32
33 #朴素的串匹配算法,返回匹配的起始位置
34 def naive_matching(self, p): #self为目标字符串,t为要查找的字符串
35 if not isinstance(self, string) and not isinstance(p, string):
36 raise stringTypeError
37 m, n = p.length(), self.length()
38 i, j = 0, 0
39 while i < m and j < n:
40 if p.get_value_list()[i] == self.get_value_list()[j]:#字符相同,考虑下一对字符
41 i, j = i+1, j+1
42 else: #字符不同,考虑t中下一个位置
43 i, j = 0, j-i+1
44 if i == m: #i==m说明找到匹配,返回其下标
45 return j-i
46 return -1
47
48 #kmp匹配算法,返回匹配的起始位置
49 def matching_KMP(self, p):
50 j, i = 0, 0
51 n, m = self.length(), p.length()
52 while j < n and i < m:
53 if i == -1 or self.get_value_list()[j] == p.get_value_list()[i]:
54 j, i = j + 1, i + 1
55 else:
56 i = string.gen_next(p)[i]
57 if i == m:
58 return j - i
59 return -1
60
61 # 生成pnext表
62 @staticmethod
63 def gen_next(p):
64 i, k, m = 0, -1, p.length()
65 pnext = [-1] * m
66 while i < m - 1:
67 if k == -1 or p.get_value_list()[i] == p.get_value_list()[k]:
68 i, k = i + 1, k + 1
69 pnext[i] = k
70 else:
71 k = pnext[k]
72 return pnext
73
74 #把old字符串出现的位置换成new字符串
75 def replace(self, old, new):
76 if not isinstance(self, string) and not isinstance(old, string)
77 and not isinstance(new, string):
78 raise stringTypeError
79
80 while self.matching_KMP(old) >= 0:
81 #删除匹配的旧字符串
82 start = self.matching_KMP(old)
83 print("依次发现的位置:",start)
84 for i in range(old.length()):
85 self.delitem(start)
86 #末尾情况下时append追加的,顺序为正;而前面的地方插入为前插;所以要分情况
87 if start<self.length():
88 for i in range(new.length()-1, -1, -1):
89 self.insert(start,new.value[i])
90 else:
91 for i in range(new.length()):
92 self.insert(start,new.value[i])
93
94
95
96 if __name__=="__main__":
97
98 a = string("abc")
99 print("字符串长度:",a.length())
100 a.printall()
101 b = string("abcbccdabc")
102 print("字符串长度:", b.length())
103 b.printall()
104 print("朴素算法_匹配的起始位置:",b.naive_matching(a),end=" ")
105 print("KMP算法_匹配的起始位置:",b.matching_KMP(a))
106 c = string("xu")
107 print("==")
108 b.replace(a,c)
109 print("替换后的字符串是:")
110 b.printall()
111 print(b.get_value_list())