Python数据结构与算法分析(第二版)答案 - 第三章(未完)

本人手写或借阅资料,仅供参考,有错误欢迎指正。

import random
from pythonds.basic import Stack, Queue, Deque

#中序表达式到后序表达式的转换

#3.1 修改从中序到后序的转换算法,使其能处理异常情况。

def infixToPostfix(indixexpr):
    prec = {'*':3, '/':3, '+':2, '-':2, '(':1}
    opStack = Stack()
    tokenList = indixexpr.split()
    postfixlist = []
    try:
        for token in tokenList:
            if isnumber(token):
                postfixlist.append(token)
            elif token == '(':
                opStack.push(token)
            elif token == ')':
                toptoken = opStack.pop()
                while toptoken != '(':
                    postfixlist.append(toptoken)
                    toptoken = opStack.pop()
            else:
                while (not opStack.isEmpty()) and (prec[opStack.peek()] >= prec[token]):
                    postfixlist.append(opStack.pop())
                opStack.push(token)

        while not opStack.isEmpty():
            postfixlist.append(opStack.pop())

        return " ".join(postfixlist)

    except:
        return "中序表达式格式错误"

#计算后序表达式

#3.2 修改计算后序表达式的算法,使其能处理异常情况。

def postfixEval(postfixExpr):
    opStack = Stack()
    tokenList = postfixExpr.split()
    try:
        for token in tokenList:
            if isnumber(token):
                opStack.push(int(token))
            else:
                operatenum2 = opStack.pop()
                operatenum1 = opStack.pop()
                res = domath(token, operatenum1, operatenum2)
                opStack.push(res)
        return opStack.pop()
    except:
        return "后序表达式格式错误"

#3.3 结合从中序到后序的转换算法以及计算后序表达式的算法,实现直接的中序计算。在计

#算时,应该使用两个栈从左往右处理中序表达式标记。一个栈用于保存运算符,另一个

#用于保存操作数。

def infixEval(infixExpr):
    opStack = Stack()
    signStack = Stack()
    tokenList = infixExpr.split()
    
    for token in tokenList:
        if token in ['+', '-', '*', '/', '(', ')']:
            if token == ')':
                while signStack.peek() != '(':
                    operatenum2 = opStack.pop()
                    signlabel = signStack.pop()
                    operatenum1 = opStack.pop()
                    res = domath(signlabel, operatenum1, operatenum2)
                    opStack.push(res)
                signStack.pop()
            else:
                signStack.push(token)
        else:
            opStack.push(int(token))

    while not signStack.isEmpty():
        operatenum2 = opStack.pop()
        signlabel = signStack.pop()
        operatenum1 = opStack.pop()
        res = domath(signlabel, operatenum1, operatenum2)
        opStack.push(res)

    return opStack.pop()                  

def domath(operation, num1, num2):
    if operation == '+':
        return num1 + num2
    elif operation == '-':
        return num1 - num2
    elif operation == '*':
        return num1 * num2
    else:
        return num1 / num2

def isnumber(s):
    try:
        float(s)
        return True
    except ValueError:  
        return False

def infixToPostfixtest():
    s = "( 11 + 2 ) * 3"
    print(infixToPostfix(s))
    print(postfixEval(infixToPostfix(s)))

def infixEvaltest():
    print(infixEval("( ( ( 1 + 2 ) * 3 ) - ( 4 + 5 + 6 - 7 ) ) * 8"))

#3.5 使用列表实现队列抽象数据类型,将列表的后端作为队列的尾部。

class Myqueue():

    def __init__(self):
        self.data = []
    
    def enqueue(self, v):
        self.data.insert(0, v)

    def dequeue(self):
        return self.data.pop()

#队列,约瑟夫环问题(传土豆)

#3.9 修改传土豆模拟程序,允许随机计数,从而使每一轮的结果都不可预测

def hotpotato(namelist):
    simqueue = Queue()
    for name in namelist:
        simqueue.enqueue(name)

    while simqueue.size() > 1:
        num = random.randrange(simqueue.size()*2)
        for i in range(num):
            simqueue.enqueue(simqueue.dequeue())
        simqueue.dequeue()
    return simqueue.dequeue()

def hotpotatotest():
    print(hotpotato(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']))

#3.10 基数排序器:

def Cardinalsort(l):
    res = []
    qlist = []
    masterqueue = Queue()
    maxlen = 0 
    length = len(l)
    for i in range(10):
        qlist.append(Queue())
    for num in l:
        maxlen = max(maxlen, len(str(num)))
        masterqueue.enqueue(num)
    for i in range(1, maxlen + 1):
        for _ in range(length):
            cur = masterqueue.dequeue()
            if len(str(cur)) < i:
                masterqueue.enqueue(cur)
            else:
                slavenum = str(cur)[-i]
                qlist[int(slavenum)].enqueue(cur)
        for j in range(10):
            while not qlist[j].isEmpty():
                masterqueue.enqueue(qlist[j].dequeue())
    while not masterqueue.isEmpty():
        res.append(masterqueue.dequeue())
    return res

def Cardinalsorttest():
    ml = [666, 1, 24, 3, 67, 9, 45]
    print(Cardinalsort(ml))

#3.11 HTML 中也存在括号匹配问题。标签有开始和结束两种形式,并

#且需要互相匹配才能正确描述网页内容

def htmlchecker():
    htstack = Stack()
    isvalid = True
    idx = 0
    tmp = ''
    with open("E:\Ace_exercise\Cpython_exercise\homework\homework3_html.html") as htmlobj:
        htmlcontents = htmlobj.read()
        try:
            while idx < len(htmlcontents) and isvalid:
                if htmlcontents[idx] == '<' and idx + 1 < len(htmlcontents) and htmlcontents[idx + 1] != '/':
                    idx += 1
                    while htmlcontents[idx] != '>':
                        tmp += htmlcontents[idx]
                        idx += 1
                    htstack.push(tmp)
                    tmp = ''
                elif htmlcontents[idx] == '<' and idx + 1 < len(htmlcontents) and htmlcontents[idx + 1] == '/':
                    idx += 2
                    while htmlcontents[idx] != '>':
                        tmp += htmlcontents[idx]
                        idx += 1
                    if htstack.pop() != tmp:
                        isvalid = False
                    tmp = ''
                else:
                    idx += 1
        except:
            return False
        if not isvalid or not htstack.isEmpty():
            return False
        return True

def htmlcheckertest():
    print(htmlchecker())

#双端队列,回文检测器

#3.12 扩展代码清单3-15 中的回文检测器,使其可以处理包含空格的回文。如果忽略其中的

#空格,那么I PREFER PI 就是回文。

def palchecker(aString):
    charDeque = Deque()
    for ch in aString:
        if ch == ' ':
            continue
        charDeque.addFront(ch)
    stillEqual = True
    while charDeque.size() > 1 and stillEqual:
        if charDeque.removeFront() != charDeque.removeRear():
            stillEqual = False
    return stillEqual

def palcheckertest():
    print(palchecker('I PREFER PI'))

#3.13 本章通过计算列表中节点的个数来实现length 方法。另一种做法是将节点个数作为额

#外的信息保存在列表头中。请修改UnorderedList 类的实现,使其包含节点个数信息,

#并且重新实现length 方法。

#3.14 实现remove 方法,使其能正确处理待移除元素不在列表中的情况

#3.17 实现__str__方法,使列表按照Python 的方式来显示(使用方括号)

#3.18 实现无序列表抽象数据类型剩余的方法:append、index、pop 和insert。

#3.19 实现UnorderedList 类的slice 方法。

class Node():
    
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def  getData(self):
        return self.data
    
    def getNext(self):
        return self.next
    
    def setData(self, newdata):
        self.data = newdata

    def setNext(self, newnext):
        self.next = newnext

class UnorderedList():
    
    def __init__(self):
        self.head = None
        self.mlength = 0

    def __str__(self):
        res = ""
        cur = self.head
        while cur:
            res += str(cur.getData())
            cur = cur.getNext()
        return '[' + res + ']'

    def append(self, other):
        cur = self.head
        while cur.getNext():
            cur = cur.getNext()
        cur.setNext(other.head)

    def index(self, v):
        idx = 0
        cur = self.head
        while cur and cur.getData() != v:
            cur = cur.getNext()
            idx += 1
        if not cur:
            return -1
        return idx      

    def pop(self):
        cur = self.head
        if not self.mlength:
            print ("空列表, 无法弹出")
            return
        pre = None
        while cur.getNext():
            pre = cur
            cur = cur.getNext()
        if not pre:
            self.head = None
            self.mlength -= 1
            return cur.getData()
        else:
            pre.setNext(None)
            self.mlength -= 1
            return cur.getData()

    def insert(self, idx, v):
        if idx < 0:
            return "索引错误"
        if idx == 0:
            self.add(v)
            return 
        cur = self.head
        idx -= 1
        while cur and idx:
            cur = cur.getNext()
            idx -= 1
        newNode = Node(v)
        nex = cur.getNext()
        cur.setNext(newNode)
        newNode.setNext(nex)

    def slice(self, start, end):
        if self.mlength < end - start:
            return "越界"
        tmp = str(self) 
        return '[' + tmp[start + 1: end + 1] + ']'

    def isEmpty(self):
        return self.head == None
    
    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp
        self.mlength += 1

    def length1(self):
        cur = self.head
        count = 0
        while cur != None:
            count += 1
            cur = cur.getNext()
        return count
    
    def length2(self):
        return self.mlength

    def search(self, item):
        cur = self.head
        found = False
        while cur != None and not found:
            if cur.getData() == item:
                found = True
            else:
                cur = cur.getNext()
        return found

    def remove(self, item):
        cur = self.head
        pre = None
        found = False
        while cur and not found:
            if cur.getData() == item:
                found = True
            else:
                pre = cur
                cur = cur.getNext()
        if not cur:
            print("无此元素")
            return 
        if not pre:
            self.head = cur.getNext
        else:
            pre.setNext(cur.getNext())
        self.mlength -= 1
            
def unorderedlisttest1():
    ul = UnorderedList()
    ur = UnorderedList()
    print(ul.pop())
    ul.add(5)
    print(ul.length2())
    ur.add(6)
    ul.add(7)
    ul.add(8)
    print(ul.length2())
    ul.remove(0)
    print(ul.length2())
    ul.remove(5)
    print(ul.length2())
    print(ul.length1())
    print(str(ul))
    while not ul.isEmpty():
        print(ul.pop())
    ul.add(7)
    ul.add(8)
    print(str(ul))
    print(str(ur))
    ul.append(ur)
    print(str(ul))
    print(ul.index(6))
    ul.insert(0,4)
    ul.insert(2,5)
    print(str(ul))
    print(ul.slice(0,2))

#3.20 实现有序列表抽象数据类型剩余的方法

class OrderedList():

    def __init__(self):
        self.head = None
    
    def __str__(self):
        res = ""
        cur = self.head
        while cur:
            res += str(cur.getData())
            cur = cur.getNext()
        return '[' + res + ']'
    
    def isEmpty(self):
        return self.head == None

    def length(self):
        cur = self.head
        count = 0
        while cur:
            count += 1
            cur = cur.getNext()
        return count
    
    def remove(self, v):
        cur = self.head
        pre = None
        found = False
        while cur and not found:
            if cur.getData() == v:
                found = True
            else:
                pre = cur
                cur = cur.getNext()
        if not cur:
            print("无此元素")
            return 
        if not pre:
            self.head = cur.getNext
        else:
            pre.setNext(cur.getNext())
        self.mlength -= 1

    def search(self, v):
        cur = self.head
        found = False
        stop = False
        while cur and not found and not stop:
            if cur.getData() == v:
                found = True
            else:
                if cur.getData() > v:
                    stop = True
                else:
                    cur = cur.getNext()
        
        return found

    def add(self, v):
        cur = self.head
        pre = None
        stop = False
        while cur and not stop:
            if cur.getData() > v:
                stop = True
            else:
                pre = cur
                cur = cur.getNext()
            
        temp = Node(v)
        if pre == None:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(cur)
            pre.setNext(temp)

#3.21 思考有序列表和无序列表的关系。能否利用继承关系来构建更高效的实现?试着实现这

#个继承结构。

class OrderedFromUnorederedlist(UnorderedList):

    def __init__(self):
        super().__init__()

    def search(self, v):
        cur = self.head
        found = False
        stop = False
        while cur and not found and not stop:
            if cur.getData() == v:
                found = True
            else:
                if cur.getData() > v:
                    stop = True
                else:
                    cur = cur.getNext()
        
        return found

    def add(self, v):
        cur = self.head
        pre = None
        stop = False
        while cur and not stop:
            if cur.getData() > v:
                stop = True
            else:
                pre = cur
                cur = cur.getNext()
            
        temp = Node(v)
        if pre == None:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(cur)
            pre.setNext(temp)

def OrderedFromUnorederedlisttest():
    ol = OrderedFromUnorederedlist()
    ol.add(67)
    ol.add(35)
    ol.add(97)
    ol.add(22)
    print(str(ol))
    print(ol.index(97))

#3.22 使用链表实现栈

class UnorderedListStack(UnorderedList):
    
    def __init__(self):
        super().__init__()

    def stackpush(self, v):
        self.add(v)

    def stackpop(self):
        if self.mlength <= 0:
            return False
        self.mlength -= 1
        cur = self.head
        if cur.getNext():
            self.head = cur.getNext()
        return cur.getData()

def UnorderedListStacktest():
    us = UnorderedListStack()
    us.stackpush(5)
    us.stackpush(6)
    print(us.stackpop())
    print(us.stackpop())
    print(us.stackpop())

#3.27 请用Python 实现双向链表。

class DoubleNode(Node):

    def __init__(self, initdata):
        super().__init__(initdata)
        self.pre = None

    def getpre(self):
        return self.pre

    def setpre(self, newpre):
        self.pre = newpre

class DoubleList(UnorderedList):

    def __init__(self):
        super().__init__()       

    def add(self, item):
        temp = DoubleNode(item)
        temp.setNext(self.head)
        if self.head:
            self.head.setpre(temp)
        self.head = temp
    
    def remove(self, v):
        cur = self.head
        pre = None
        found = False
        while not found:
            if cur.getData() == v:
                found = True
            else:
                pre = cur
                cur = cur.getNext()
        if not pre:
            self.head = cur.getNext()
            cur.getNext().setpre(None)
        else:
            pre.setNext(cur.getNext())
            pre.getNext().setpre(pre)

def DoubleListtest():
    dl = DoubleList()
    dl.add(4)
    dl.add(3)
    dl.add(2)
    dl.add(1)
    print(str(dl))
    dl.remove(3)
    print(str(dl))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值