【数据结构与算法——python】基本结构

基本结构

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items) - 1]

    def size(self):
        return len(self.items)

单一括号匹配算法

from basic.Stack import Stack

# 1.初始化,建立栈
# 2.遍历字符串
#   (1)如果是左括号就存入栈
#   (2)如果是右括号:
#       a.没有与之匹配的左括号(栈为空),返回False
#       b.有可以匹配的左括号,二者抵消
# 3.如果栈内没有剩余左括号,返回True,否则返回False
def parChecker(symbolString):
    # 初始化
    s = Stack()
    index = 0

    while index < len(symbolString):
        symbol = symbolString[index]
        if symbol == "(":
            s.push(symbol)
        else:
            if s.isEmpty():
                return False
            else:
                s.pop()
        index += 1

    if s.isEmpty():
        return True
    else:
        return False

通用括号匹配

from basic.Stack import Stack
# 1.初始化,建立栈
# 2.遍历字符串
#   (1)如果是左括号就存入栈
#   (2)如果是右括号:
#       a.没有与之匹配的左括号(栈为空),返回False
#       b.有可以匹配的左括号,二者抵消
# 3.如果栈内没有剩余左括号,返回True,否则返回False
def parChecker2(symbolString):
    s=Stack()
    index=0

    while index<len(symbolString):
        symbol=symbolString[index]
        if symbol in "([{":
            s.push(symbol)
        else:
            if s.isEmpty():
                return False
            else:
                top=s.pop()
                if not matches(top,symbol):
                    return False
        index+=1
    if s.isEmpty():
        return True
    else:
        return False

def matches(open,close):
    opens="([{"
    closers=")]}"
    return opens.index(open)==closers.index(close)

十进制转二进制

from basic.Stack import Stack

# 1.创建一个栈
# 2. rem存放ducNumber除2的余数,入栈。decNumber除2
# 3. 反向输出,出栈
def divideBy2(decNumber):
    remstack=Stack()

    while decNumber>0:
        rem=decNumber%2
        remstack.push(rem)
        decNumber//=2

    binString =""
    while not remstack.isEmpty():
        binString+=str(remstack.pop())

    return binString

16进制以下通用进制转换

from basic.Stack import Stack

# 1.设置一个digits来存放表示字符
# 2.创建栈
# 3.进制转换,入栈
# 4.出栈对比digits,输出表示字符
def baseConverter(decNumber, base):
    digits = "0123456789ABCDEF"

    remstack = Stack()

    while decNumber > 0:
        rem = decNumber % base
        remstack.push(rem)
        decNumber //= base

    newString = ""
    while not remstack.isEmpty():
        newString += digits[remstack.pop()]

    return newString

表达式

中缀表达式

操作符介于操作数中间的表示法,称为中缀表达式

优先级

  • 引入了“优先级”的概念来消除混淆
    • 规定高优先级的操作符先计算
    • 相同优先级操作符从左到右依次计算
  • 引入括号来表示强制优先级,括号的优先级最高;在嵌套的括号中,内层的优先级更高

**全括号中缀表达式:**在所有表达式两边都加上括号

前缀和后缀表达式

以操作符相对于操作数的位置来定义.

操作符的次序完全决定了运算的次序,不再有混淆,不需要括号

中缀表达式前缀表达式后缀表达式
A + B A+B A+B + A B +AB +AB A B + AB+ AB+
A + B ∗ C A+B*C A+BC + A ∗ B C +A*BC +ABC A B C ∗ + ABC*+ ABC+
( A + B ) ∗ C (A+B)*C (A+B)C ∗ + A B C *+ABC +ABC A B + C ∗ AB+C* AB+C
A + B ∗ C + D A+B*C+D A+BC+D + + A ∗ B C D ++A*BCD ++ABCD A B C ∗ + D + ABC*+D+ ABC+D+
( A + B ) ∗ ( C + D ) (A+B)*(C+D) (A+B)(C+D) ∗ + A B + C D *+AB+CD +AB+CD A B + C D + ∗ AB+CD+* AB+CD+
A ∗ B + C ∗ D A*B+C*D AB+CD + ∗ A B ∗ C D +*AB*CD +ABCD A B ∗ C D ∗ + AB*CD*+ ABCD+
A + B + C + D A+B+C+D A+B+C+D + + + A B C D +++ABCD +++ABCD A B + C + D + AB+C+D+ AB+C+D+
中缀表达式转换前缀或后缀
  • 中缀表达式转换为全括号表达式

  • 遇到括号时,将操作符替代右括号的位置,删去左括号,得到后缀表达式

  • 遇到括号时,将操作符替代左括号的位置,删去右括号,得到前缀表达式

中缀转后缀算法

from basic.Stack import Stack


# 1.创建字典,用于存放操作符优先级
# 2.创建栈,用于暂存操作符;
#   创建空列表,用于存放后缀表达式;
#   解析表达式为单词列表
# 3.遍历单词列表
#   (1)如果为操作数,就添加到后缀表达式列表
#   (2)如果为左括号,放入操作符栈
#   (3)如果为右括号,反复弹出栈顶操作符存入表达式列表,直到弹出左括号
#   (4)如果为操作符:
#       a.如果栈顶操作符优先级更大,则先弹出栈顶操作符存入表达式列表,再将操作符入栈
#       b.否则直接入栈
# 4.遍历结束后如果有操作符未弹出,则按出栈顺序存入表达式列表
# 5.用join合成后缀表达式字符串
def infixToPostfix(infixexpr):
    prec = {}
    prec["*"] = 3
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1

    opStack = Stack()
    postfixList = []
    tokenList=list(infixexpr)

    for token in tokenList:
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            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)

后缀表达式求值

from basic.Stack import Stack


# 1.将中缀转换为后缀表达式;
#   创建空栈,存放操作数
#   tokenList获得单词列表
# 2.遍历tokenList:
#   (1)如果为数字,存放到栈中
#   (2)如果为操作符,取出两个操作数进行计算,结果重新入栈
# 3.计算完毕,返回结果
def postfixEval(postfixExpr):
    postfixExpr = infixToPostfix(postfixExpr)
    operandStack = Stack()
    tokenList = list(postfixExpr)

    for token in tokenList:
        if token in "0123456789":
            operandStack.push(int(token))
        else:
            operand2 = operandStack.pop()
            operand1 = operandStack.pop()
            result = doMath(token, operand1, operand2)
            operandStack.push(result)
    return operandStack.pop()


def doMath(op, op1, op2):
    if op == "*":
        return op1 * op2
    elif op == "/":
        return op1 / op2
    elif op == "+":
        return op1 + op2
    else:
        return op1 - op2


# 1.创建字典,用于存放操作符优先级
# 2.创建栈,用于暂存操作符;
#   创建空列表,用于存放后缀表达式;
#   解析表达式为单词列表
# 3.遍历单词列表
#   (1)如果为操作数,就添加到后缀表达式列表
#   (2)如果为左括号,放入操作符栈
#   (3)如果为右括号,反复弹出栈顶操作符存入表达式列表,直到弹出左括号
#   (4)如果为操作符:
#       a.如果栈顶操作符优先级更大,则先弹出栈顶操作符存入表达式列表,再将操作符入栈
#       b.否则直接入栈
# 4.遍历结束后如果有操作符未弹出,则按出栈顺序存入表达式列表
# 5.用join合成后缀表达式字符串
def infixToPostfix(infixexpr):
    prec = {}
    prec["*"] = 3
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1

    opStack = Stack()
    postfixList = []
    tokenList = list(infixexpr)

    for token in tokenList:
        if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789":
            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)

队列

class Queue:
    def __init__(self):
        self.item = []

    def isEmpty(self):
        return self.item == []

    def enqueue(self, item):
        self.item.insert(0, item)

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

    def size(self):
        return len(self.item)

热土豆问题

from basic.Queue import Queue


# 1.创建一个空队列
# 2.将列表存放入队列
# 3.当队列中人数大于1的情况下:
#   (1)每传递一次,队首入队,重新从队尾入队
#   (2)每完成一轮,队首出队
# 4.最后队列中剩下一个元素

def hotPotato(namelist, num):
    simqueque = Queue()

    for name in namelist:
        simqueque.enqueue(name)

    while simqueque.size() > 1:
        for i in range(num):
            simqueque.enqueue(simqueque.dequeue())

        simqueque.dequeue()

    return simqueque.dequeue()

打印机问题

  • 实例配置:
    一个实验室中,在任意的一个小时内,有大约10名学生在场, 这一个小时内,每人会发起约2次左右的打印,每次1~20页

  • 打印机性能:
    草稿模式:每分钟10页
    正常模式:每分钟5页,质量较高

Q:如何设置打印机模式,让大家都不会等太久的前提下提高打印质量?

  • 对象:

    • 打印任务:提交时间、打印页数
    • 打印队列:具有FIFO性质的打印任务队列
    • 打印机:打印速度、是否忙
  • 过程:生成和提交任务

    • 确定生成概率:每小时有10个学生提交20个作业。

      概率为:每180秒会有1个作业生成—— 1 180 / s \frac{1}{180}/s 1801/s

    • 确定打印页数:1~20页概率相同

  • 过程:实施打印

    • 当前打印作业:正在打印的作业
    • 打印结束倒计时:开始时倒计时,为0时处理下一个任务
  • 模拟时间:

    • 统一的时间框架:以 秒 秒 为单位,设置结束时间
    • 同步所有过程:在一个单位时间内,对生成任务和打印任务各处理一次
  • 模拟流程

    • 创建打印队列对象
    • 时间按照 秒 秒 的单位流逝
      • 按照概率生成打印作业,加入打印队列
      • 如果打印机空闲,且队列不空,则取出队首作业打印,记录此作业等待时间
      • 如果打印机忙,则按照打印速度进行1秒打印
      • 如果当前作业打印完成,则打印机进入空闲
    • 时间用尽,开始统计平均等待时间
    • 作业的等待时间:
      • 生成作业时,记录生成的时间戳
      • 开始打印时,当前时间减去生成时间即可
    • 作业的打印时间:
      • 生成作业时,记录作业的页数
      • 开始打印时,页数除以打印速度即可
# 实例配置:
#   一个实验室中,在任意的一个小时内,有大约10名学生在场,
#   这一个小时内,每人会发起约2次左右的打印,每次1~20页
#
# 打印机性能:
#   草稿模式:每分钟10页
#   正常模式:每分钟5页,质量较高
#
# 如何设置打印机模式,让大家都不会等太久的前提下提高打印质量
#
#
#
from basic.Queue import Queue

import random


class Printer:

    def __init__(self, ppm):
        self.pagerate = ppm  # 打印速度
        self.currentTask = None  # 打印任务
        self.timeRemaining = 0  # 任务倒计时

    # 进行1秒打印
    #   如果当前任务不为空,进行倒计时
    #   如果倒计时结束,任务结束
    def tick(self):
        if self.currentTask != None:
            self.timeRemaining -= 1
            if self.timeRemaining <= 0:
                self.currentTask = None

    # 判断打印机是否忙
    def busy(self):
        if self.currentTask != None:
            return True
        else:
            return False

    # 打印新作业
    def startNext(self, newtask):
        self.currentTask = newtask
        self.timeRemaining = newtask.getPages() * 60 / self.pagerate


class Task:
    def __init__(self, time):
        self.timestamp = time  # 生成时间戳
        self.pages = random.randrange(1, 21)  # 打印页数

    def getStamp(self):
        return self.timestamp

    def getPages(self):
        return self.pages

    def waitTime(self, currenttime):
        return currenttime - self.timestamp


def newPrintTask():
    num = random.randrange(1, 181)  # 1/180的概率生成作业
    if num == 180:
        return True
    else:
        return False


# 模拟
def simulation(numSeconds, pagesPerMinute):
    labprinter = Printer(pagesPerMinute)
    printQueue = Queue()
    waitingtimes = []

    for currentSecond in range(numSeconds):
        if newPrintTask():
            task = Task(currentSecond)
            printQueue.enqueue(task)

        if (not labprinter.busy()) and (not printQueue.isEmpty()):
            nexttask = printQueue.dequeue()
            waitingtimes.append(nexttask.waitTime(currentSecond))
            labprinter.startNext(nexttask)

        labprinter.tick()

    averageWait = sum(waitingtimes) / len(waitingtimes)
    print("Average Wait %6.2f secs %3d tasks remaining." % (averageWait, printQueue.size()))

for i in range(10):
    simulation(3600,10)

双端队列

class Deque:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def addFront(self, item):
        self.items.append(item)

    def addRear(self, item):
        self.items.insert(0, item)

    def removeFront(self):
        return self.items.pop()

    def removeRear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

回文词

from basic.Deque import Deque

# 1.将字符串存入双端队列
# 2.取出双端队列两端进行比较
def palchecker(aString):
    chardeque = Deque()

    for ch in aString:
        chardeque.addRear(ch)

    while chardeque.size() > 1:
        first = chardeque.removeFront()
        last = chardeque.removeRear()
        if first != last:
            return False

    return True

列表

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

    def isEmpty(self):
        return self.head == None

    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            current = current.getNext()

        return count

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

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                prevoius = current
                current = current.getNext()

        if previous == None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

有序表

class OrderedList:
    def __init__(self):
        self.head = None

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

    def add(self, item):
        current = self.head
        previous = None
        stop = False
        while current != None and not stop:
            if current.getData() > item:
                stop = True
            else:
                previous = current
                current = current.getNext()

        temp = Node(item)
        if previous == None:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(current)
            previous.setNext(temp)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZhShy23

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值