串的Python数据结构及简单模式匹配算法

 本文主要是描述数据结构中串的数据类型,并且通过Python语言对其实现。并且撰写了简单的模式匹配算法Brute force模式匹配算法;下篇有关的文章将书写KMP算法的实现过程,但数据结构仍然沿用本篇文章的代码。

# 1、串的抽象数据类型 #

    from abc import ABCMeta,abstractmethod,abstractproperty

    class IString(metaclass = ABCMeta):
        @abstractmethod
        def clear(self):
            '''将字符串置成空串'''
            pass
        @abstractmethod
        def isEmpty(self):
            '''判断是否为空串'''
            pass
        @abstractmethod
        def length(self):
            '''返回串的长度'''
            pass
        @abstractmethod
        def charAt(self,i):
            '''读取并返回串中的第i个数据元素'''
            pass
        @abstractmethod
        def subString(self,begin,end):
            '''返回位序号从begin到end-1的子串'''
            pass
        @abstractmethod
        def insert(self,i,str):
            '''在第i个字符之前插入子串str'''
            pass
        @abstractmethod
        def delete(self,begin,end):
            '''删除位序号从begin到end-1的子串'''
            pass
        @abstractmethod
        def compareTo(self,str):
            '''比较str和当前字符串的大小'''
            pass
        @abstractmethod
        def indexOf(self,str,begin):
            '''从位序号为begin的字符开始搜索与str相等的子串'''
            pass

        @abstractmethod
        def display(self):
            '''打印字符串'''
            pass

# 2、顺序串的实现 #
    from IString import *
    import time
    '''
        顺序串,其逻辑结构与顺序表类似
            存储结构选用数组;
        这里拿顺序串举例而不用链串的原因为:
            链串可以分为单字符链表和块链(即一个子串占一个节点),单字符链串存储效率低,而块链操作十分复杂。博主也未深究;
    '''
    class SqString(IString):
        '''
            初始化
        '''
        def __init__(self,obj=None):
            if obj is None: 
                self.strValue = []  #用数组来存放串的值
                self.curLen = 0 #长度
            elif isinstance(obj,str): #以字符串构造串   isinstance()  该函数用来判断是否是已知类型  如 >>isinstance (a,int)   //    判断a是否是int类型  返回布尔值  True 或者  False
                self.curLen = len(obj)  # 以字符列表构造串
                self.strValue = [None] * self.curLen
                for i in range(self.curLen):
                    self.strValue[i] = obj[i]
            elif isinstance(obj,list): #以字符列表构造串
                self.curLen = len(obj)
                self.strValue = [None] * self.curLen
                for i in range(self.curLen):
                    self.strValue[i] = obj[i]

        def clear(self):
            '''
            将字符串置成空串
            '''
            self.curLen = 0

        def isEmpty(self):
            '''
            判断是否为空串
            '''
            return self.curLen == 0

        def length(self):
            '''
            返回串的长度
            '''
            return self.curLen

        def charAt(self,i):
            '''
                读取并返回串中的第i个位置数据元素
            '''
            if i<0 or i>=self.curLen:
                raise IndexError("String index out of range") 
            return self.strValue[i]
        
        def allocate(self,newCapacity):
            '''
                将串的长度扩充为newCapacity
            '''
            tmp = self.strValue
            self.strValue = [None] * newCapacity    #顺序表是预分配,所以扩充长度需要重新填入元素
            for i in range(self.curLen):
                self.strValue[i] = tmp[i]
            #return self.strValue
        
        def subString(self,begin,end):
            '''
            返回位序号从begin到end-1的子串
                1、判断参数是否合法(越界)
                2、构建一个空列表
                3、循环赋值
                5、返回字符串
            '''
            if begin<0 or begin>=end or end>self.curLen:
                raise IndexError("参数不合法")
            tmp = [None] * (end - begin)     # 空列表
            for i in range(begin,end):
                tmp[i-begin] = self.strValue[i] #复制子串
            return SqString(tmp)

        def insert(self,i,str):
            '''
            在第i个字符之前插入子串str
                判断插入位置是否合法
                元素后移
                字符串插入
                长度增加
            '''
            if i<0 or i>self.curLen:
                raise IndexError("插入位置不合法")
            length = str.length()
            newCapacity = self.curLen + length
            self.allocate(newCapacity)
            for j in range(self.curLen-1,i-1,-1):
                self.strValue[j+length] = self.strValue[j]
            for j in range(i,i+length):
                self.strValue[j] = str.charAt(j-i)
            self.curLen = newCapacity

        def delete(self,begin,end):
            '''
            删除位序号从begin到end-1的子串
                1、判断删除位置是否合法;{例如: begin<0 , begin>end ,end > curLen}
                2、交换删除位置的值
                3、缩短长度
            '''
            if begin<0 or begin>=end or end>self.curLen:
                raise IndexError("删除不合法")
            for i in range(begin,end):
                self.strValue[i] = self.strValue[i+end-begin]
            self.curLen = self.curLen-(end - begin)

        def compareTo(self,str):
            '''
            比较str和当前字符串的大小
                字符串比较需要逐字比较
            '''
            n = self.curLen if self.curLen<str.length() else str.length()
            for i in range(n):
                if self.strValue[i]>str.charAt(i):
                    return 1
                if self.strValue[i] < str.charAt(i):
                    return -1
            if self.curLen > str.length():
                return 1
            elif self.curLen < str.length():
                return -1
            return 0


        def indexOf(self,str,begin):
            '''
                从位序号为begin的字符开始搜索与str相等的子串
            '''
            pass

        def display(self):
            '''打印字符串'''
            for i in range(self.curLen):
                print(self.strValue[i],"\t",end='')
            print("\n")

# 3、简单模式匹配算法 #
    def BF(self,str,begin):
        '''
            Brute force模式匹配算法
                逐一匹配,每次只移动一个位置 匹配失败后从开始匹配的下一个位置开始从新匹配
                这么一看时间复杂度为 : O(n*m)
        '''
        if str.length()<=self.curLen and str is not None and self.curLen>0:
            i = begin
            length = str.length()
            while (i<=self.curLen-length):
                for j in range(length):
                    if str.charAt(j)!=self.strValue[j+i]:
                        i+=1
                        break
                    elif j == length-1:
                        return i
        return -1

本文的一些想法摘自天勤辅导书和王道辅导书;以及一些Python相关的数据结构辅导书

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值