数据结构与算法学习_变位词判断算法的Python实现

数据结构和算法是计算机技术的基本功之一,北京大学的课程深入浅出,使用Python作为载体简化了编程难度。今天快速浏览了1-17,特将笔记整理如下:

1、针对变位词判断问题,总结了4种算法,并分析其计算复杂度与空间复杂度。

2、针对Python数据类型列表与字典,对其性质、性能、实现进行了解。

3、线性结构初探-栈。Stack。使用栈编写括号识别算法。

'''1 变位词判断问题'''

#写一个目Bool函数判断单词是否为变位关系

#假定不存在大小写问题且长度相等

#方法1 逐字符查询

#单词1的字符依次在2中检查是否存在,每个都找到是变位词,有一个

#找不到就不是变位词

#Python中字符串不可变,先复制到列表list中

def anagramSolution(s1,s2):

    alist=list(s2)

    pos1=0

    stillOK=True

    while pos1

        pos2=0

        found=False

        while pos2< len(alist) and not found:#依次查找单词2中每一个字符

            if s1[pos1]==s2[pos2]:

                found=True

            else: 

                pos2+=1#found 

        if found:

            alist[pos2]=pos1+1#找到,做标记

        else:

            stillOK=False

        pos1+=1

    return stillOK

s1="wjk1"

s2="1wkj"

s3="1wje"

print(anagramSolution(s1,s2),anagramSolution(s1,s3))

#每个字符的对比次数1,2,。。。,n,共1/2n(n+1),O(n^2)

#方法2 排序比较

#各自按字母顺序排序,再逐字符比较

def anagramS2(s1,s2):

    alist1=list(s1)

    alist2=list(s2)

    alist1.sort()#实际上排序耗时O(nlogn)以上

    alist2.sort()

    pos=0

    match=True

    while pos

        if alist1[pos]!=alist2[pos]:#只有一个循环O(n)

            match=False

        else:

            pos+=1

    return match

print(anagramS2(s1,s2),anagramS2(s1,s3))

#排序比较的数量级就是排序的数量级

#方法3: 暴力法

#穷尽s1字符全排列,看s2是否出现

#n个字符全排有n!种可能

#方法4 计数比较

#26个字母出现次数都相同,则一定是变位词

def anagramS3(s1,s2):

    c1=[0]*26#列表扩张方法

    c2=[0]*26

    for i in range(len(s1)):

        pos=ord(s1[i])-ord('a')#定位到s1中第i个字符相对于a的位置

        c1[pos]+=1#计数

    for i in range(len(s2)):

        pos=ord(s2[i])-ord('a')#定位到s2中第i个字符相对于a的位置

        c2[pos]+=1#计数

    j=0

    stillOK=True

    while j<26 and stillOK:

        if c1[j]!=c2[j]:

            stillOK=False

        else:

            j+=1

    return stillOK

print(anagramS2(s1,s2),anagramS2(s1,s3))

#O(n),2n+26 无敌

#依赖两个长度为26的计数器列表,需要更多存储空间-空间换时间

'''对比Python中list和dict数据类型的性能'''

#dict: add b[k]=v delete-pop has_key update b[k] copy

#List: v=a[i] a[i]=v, O(1); lst.append(v) O(1); lst+=[v] O(n+k)

#list.sort() O(nlogn)

#python list.pop(i)的实现是i后元素向前挪位复制,保证按索引取值和赋值很快O(1)

#dict从key取值,取值赋值,contain(in)最快

#in操作在字典中不随大小增长

#有序数据项的集合,每个数据项都有唯一的前驱和后继

#每个项都有唯一的【前驱】和【后继】

#左端右端,顶端底端

#有的只允许一端添加,有的双端可添加移除,有的中间位置也可

#四种基本结构,共同点是数据项之间只存在先后次序关系

#栈Stack-抽象数据类型

#只在一端加入和移除,后进先出

#离栈底越近保存时间越长-反转次序

#例如浏览器的后退,word的undo

"""

Stack()

push(item)

pop()

peek()窥视栈顶数据项

isEmpty()

size()

"""

#将Stack实现为Python的一个class,选用list来实现

#list[0] list[-1]末端设为栈底

class Stack:

    def __init__(self):

        self.items=[]

    def isEmpty(self):

        return self.items==[]


    def push(self,item):

        self.items.append(item)

        # self.items.insert(0,item)-栈顶首端,复杂度o(n)


    def pop(self):

        return self.items.pop()


    def peek(self):

        return self.items[len(self.items)-1]

    def size(self):

        return len(self.items)

s=Stack()

s.push('a')

s.push(3)

print(s.peek())

#栈的应用

#括号匹配

#最新的左括号应该匹配第一个右括号

def parCheck(str1):#str假设只有(()))

    s=Stack()

    balanced=True

    index=0

    while index

        symbol=str1[index]

        if symbol in "([{":

            s.push(symbol)

        else:

            if s.isEmpty():

                balanced=False

            else:

                if (s.peek()=="[" and symbol=="]") or (s.peek()=="{"and symbol=="}") or (s.peek()=="(" and symbol==")"):

                    s.pop()

                else:

                    balanced=False

        index+=1

    if balanced and s.isEmpty():

        return True

    else:

        return False

print(parCheck("({{[]}})"),parCheck("([))"))

你可能感兴趣的:(数据结构与算法学习_变位词判断算法的Python实现)