标签:size 功能 method 使用 ring 字符 class bsp pytho
1 #!/urs/bin/env python
2 # -*- coding:utf-8 -*-
3
4 #异常类
5 class stringTypeError(TypeError):
6 pass
7
8 #节点类
9 class Node(object):
10 def __init__(self, elem, next_ = None):
11 self.elem = elem
12 self.next = next_
13 #单链表类
14 class single_list(object):
15 def __init__(self):
16 self._head = None
17 self._num = 0
18
19 def __len__(self):
20 return self._num
21
22 def prepend(self,elem):
23 self._head = Node(elem, self._head)
24 self._num += 1
25
26 def append(self,elem):
27 if self._head is None:
28 self._head = Node(elem)
29 self._num += 1
30 return
31 p = self._head
32 while p.next:
33 p = p.next
34 p.next = Node(elem)
35 self._num += 1
36
37 def pop_last(self):
38 if self._head is None:
39 raise ValueError("in pop_last")
40 p = self._head
41 if p.next is None:
42 e = p.elem
43 self._head = None
44 self._num -= 1
45 return e
46 while p.next.next:
47 p = p.next
48 e = p.next.elem
49 p.next = None
50 self._num -= 1
51 return e
52
53 def delitem(self, key):
54 if key == len(self)-1:
55 self.pop_last()
56 elif 0<= key < len(self) - 1:
57 p = self._head
58 pre = None
59 num = -1
60 while p is not None:
61 num += 1
62 if key==num:
63 if not pre:
64 self._head = p.next
65 self._num -= 1
66 else:
67 pre.next = p.next
68 self._num -= 1
69 break
70 else:
71 pre = p
72 p = p.next
73 else:
74 raise IndexError
75
76 def insert(self, key, elem):
77 if key>=len(self)-1:
78 self.append(elem)
79 elif 0<=key<len(self)-1:
80 p = self._head
81 pre = None
82 num = -1
83 while p:
84 num += 1
85 if num==key:
86 if not pre:
87 self._head = Node(elem, self._head)
88 self._num += 1
89 else:
90 pre.next = Node(elem, pre.next)
91 self._num += 1
92 break
93 else:
94 pre = p
95 p = p.next
96 else:
97 raise IndexError
98
99 # 打印显示
100 def printall(self):
101 p = self._head
102 while p:
103 print(p.elem, end="")
104 if p.next:
105 print(", ", end="")
106 p = p.next
107 print("")
108
109
110 #单链表字符串类
111 class string(single_list):
112 def __init__(self, value):
113 self.value = str(value)
114 single_list.__init__(self)
115 for i in range(len(self.value)-1,-1,-1):
116 self.prepend(self.value[i])
117
118 def length(self):
119 return self._num
120
121 #获取字符串对象值的列表,方便下面使用
122 def get_value_list(self):
123 l = []
124 p = self._head
125 while p:
126 l.append(p.elem)
127 p = p.next
128 return l
129
130 def printall(self):
131 p = self._head
132 print("字符串结构:",end="")
133 while p:
134 print(p.elem, end="")
135 if p.next:
136 print("-->", end="")
137 p = p.next
138 print("")
139
140 #朴素的串匹配算法,返回匹配的起始位置
141 def naive_matching(self, p): #self为目标字符串,t为要查找的字符串
142 if not isinstance(self, string) and not isinstance(p, string):
143 raise stringTypeError
144 m, n = p.length(), self.length()
145 i, j = 0, 0
146 while i < m and j < n:
147 if p.get_value_list()[i] == self.get_value_list()[j]:#字符相同,考虑下一对字符
148 i, j = i+1, j+1
149 else: #字符不同,考虑t中下一个位置
150 i, j = 0, j-i+1
151 if i == m: #i==m说明找到匹配,返回其下标
152 return j-i
153 return -1
154
155 #kmp匹配算法,返回匹配的起始位置
156 def matching_KMP(self, p):
157 j, i = 0, 0
158 n, m = self.length(), p.length()
159 while j < n and i < m:
160 if i == -1 or self.get_value_list()[j] == p.get_value_list()[i]:
161 j, i = j + 1, i + 1
162 else:
163 i = string.gen_next(p)[i]
164 if i == m:
165 return j - i
166 return -1
167
168 # 生成pnext表
169 @staticmethod
170 def gen_next(p):
171 i, k, m = 0, -1, p.length()
172 pnext = [-1] * m
173 while i < m - 1:
174 if k == -1 or p.get_value_list()[i] == p.get_value_list()[k]:
175 i, k = i + 1, k + 1
176 pnext[i] = k
177 else:
178 k = pnext[k]
179 return pnext
180
181 #把old字符串出现的位置换成new字符串
182 def replace(self, old, new):
183 if not isinstance(self, string) and not isinstance(old, string) 184 and not isinstance(new, string):
185 raise stringTypeError
186
187 while self.matching_KMP(old) >= 0:
188 #删除匹配的旧字符串
189 start = self.matching_KMP(old)
190 print("依次发现的位置:",start)
191 for i in range(old.length()):
192 self.delitem(start)
193 #末尾情况下时append追加的,顺序为正;而前面的地方插入为前插;所以要分情况
194 if start<self.length():
195 for i in range(new.length()-1, -1, -1):
196 self.insert(start,new.value[i])
197 else:
198 for i in range(new.length()):
199 self.insert(start,new.value[i])
200
201 #self字符串里第一个属于字符串another的字符所在结点的位置
202 def find_in(self, another):
203 if not isinstance(self, string) and not isinstance(another, string):
204 raise TypeError
205 for i in range(self.length()):
206 if self.get_value_list()[i] in another.get_value_list():
207 return i
208 return -1 #没有发现
209
210 # self字符串里第一个不属于字符串another的字符所在结点的位置
211 def find_not_in(self, another):
212 if not isinstance(self, string) and not isinstance(another, string):
213 raise TypeError
214 for i in range(self.length()):
215 if self.get_value_list()[i] not in another.get_value_list():
216 return i
217 return -1 #没有发现
218
219 #从self里删除串another里的字符
220 def remove(self, another):
221 if not isinstance(self, string) and not isinstance(another, string):
222 raise TypeError
223 while self.find_in(another)>=0:
224 self.delitem(self.find_in(another))
225
226 if __name__=="__main__":
227
228 a = string("aba")
229 print("字符串长度:",a.length())
230 a.printall()
231 b = string("abaaaabadaba")
232 print("字符串长度:", b.length())
233 b.printall()
234 print("朴素算法_匹配的起始位置:",b.naive_matching(a),end=" ")
235 print("KMP算法_匹配的起始位置:",b.matching_KMP(a))
236 c = string("xu")
237 print("==")
238 b.replace(a,c)
239 print("替换后的字符串是:")
240 b.printall()
241 print(b.get_value_list())
242 d = string("dfga")
243 print("第一个属于another字符的位置:",b.find_in(d))
244 e = string("ad")
245 print("第一个不属于another字符的位置:", b.find_not_in(e))
246 b.remove(e)
247 b.printall()
数据结构:单链表结构字符串(python版)添加了三个新功能
标签:size 功能 method 使用 ring 字符 class bsp pytho
原文地址:http://www.cnblogs.com/xautxuqiang/p/6112931.html