数据结构:单链表结构字符串(python版)改进

此篇文章的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())

 

posted @ 2016-11-29 10:42  小黄人python  阅读(571)  评论(0编辑  收藏  举报