算术表达式计算程序:Python语言实现

news2024/12/23 16:35:18

算术表达式计算程序:Python语言实现

本文介绍通过Python语言实现算术表达式计算程序的过程。

我们将按照软件工程的基本步骤来介绍:

  • 需求
  • 分析
  • 设计
  • 实现

程序的需求

我们的程序具有如下功能:

  • 用户在提示符下输入一个算术表达式,然后程序会显示该表达式的值,
  • 如果该表达式无效的话,则显示错误消息。

这是程序交互的一个示例:

Enter an infix expression: 12 + 3 * 2 - 10 / 2
12 + 3 * 2 - 10 / 2
13

Enter an infix expression: 12 - 4 * 5
12 - 4 * 5
-8

Enter an infix expression: (12 - 4) * 5
( 12 - 4 ) * 5
40

Enter an infix expression: (12 - 4 * 5
( 12 - 4 * 5
Too few operators(No matching opening right parenthese found)
Portion of infix expression processed: ( 12 - 4 * 5
Operators on the stack          : [(]

Enter an infix expression: 12 - 4) * 5
12 - 4 ) * 5
Too few operators(No matching opening left parenthese found)
Portion of infix expression processed: 12 - 4 )
The stack is empty

Enter an infix expression: 12 + * 3
12 + * 3
Too few operands on the stack
Portion of infix expression processed: 12 + * 3
The stack is empty
Portion of postfix expression processed: 12 3 * +
Operands on the stack          : [36]

Enter an infix expression: 23 + 34 34
23 + 34 34
Too many operands on the stack
Portion of infix expression processed: 23 + 34 34
The stack is empty
Portion of postfix expression processed: 23 34 34 +
Operands on the stack          : [23, 68]

Enter an infix expression: 12 % 2 + 4
12 % 2 + 4
Unrecognized symbol
Portion of infix expression processed: 12 %
The stack is empty

Enter an infix expression: 12 + 4 / 0
12 + 4 / 0
integer division or modulo by zero
Portion of infix expression processed: 12 + 4 / 0
The stack is empty
Portion of postfix expression processed: 12 4 0 /
Operands on the stack          : [12]

Enter an infix expression:

我们的程序中支持的算术表达式具有以下限制:

  • 算术表达式采取中缀表示法(即日常的数学表达式)
  • 运算数只支持正整数(负整数可以通过0 - 正整数获取)
  • 运算符支持加、减、乘、除四则运算,优先级复合标准的四则运算
  • 表达式支持括号(),支持嵌套的括号()

输入输出的格式具有以下限制:

  • 输入表达式的时候,限定表达式在一行文本之内,
  • 运算数和运算符之间可以有任意空白。
  • 当用户按下了Enter键之后,按照在每个符号之间只有一个空格的项是显示表达式,
  • 在后面新的一行开始,紧跟着的是表达式的值或者错误消息,
  • 用户通过在提示符直接按下Enter键来退出。

程序中检测并报告一些输入错误:

  • 不匹配的括号,
  • 表达式包含太少的运算数,
  • 表达式包含太多的运算数,
  • 表达式包含了不识别的符号:程序期待表达式包含整数、4中运算符(+、-、*、/)以及空白(空格和制表符)。任何其他内容都是不识别的。
  • 表达式包含了除以0的情况。

程序的分析

我们计算算术表达式的处理过程主要分为两大步骤

  • 将中缀表达式转化成等价的后缀表达式,
  • 计算后缀表达式,获取结果

所以我们设计的类中,首先想到的实现中缀转后缀和计算后缀表达式的类:

  • IFToPFConverter类:中缀表达式转后缀表达式的类
  • PFEvaluator类:计算后缀表达式的类
  • Stack类:栈类,中缀表达式转后缀表达式,以及后缀表达式的计算中都会用到

另外,将输入的一行表达式转换成符号序列的功能,也需要两个类:

  • Token类:表示符号,包括运算数和运算符
  • Scanner类:扫描一行字符串,转化成符号序列

顶层采用了视图和模型的模式:

  • IFEvaluatorView类:视图类
    • 视图要求模型按照每个符号之间只有一个空格的格式来格式化表达式字符串,然后,显示格式化后的字符串。
    • 视图要求模型计算表达式,然后显示返回的值
    • 视图捕获模型所抛出的任何异常,要求模型给出当检测到错误的时候的参照条件,并且显示相应的错误信息。
  • IFEvaluatorModel类:模型类
    • 它必须能够格式化并计算表达式字符串
    • 它可以引发异常以响应字符串中的语法错误,并且报告其内部状态。

具体的类关系图如下:

evaluate_class.png

程序的设计

我们接下来给出每个类的具体接口和含义。

首先根据类关系图,给出对应的类之间接口交互图。

evaluate_interaction.png

接下来分别罗列各个类的接口和含义。

  1. IFEvaluatorView类

    • 主要的方法就一个run(),具体的代码逻辑如下图:

在这里插入图片描述

  1. IFEvaluatorModel类

    模型包括format()、evaluate()和evaluationStatus()这三个方法,下面分别说明:

    • format(expressionStr)的流程如下图:

      IFEvaluatorModel_format_flow.png

    • evaluate(expressionStr)的流程很简单:

      • 创建一个IFToPFConverter类对象,将Scanner(expressionStr)传入IFToPFConverter,获取后缀表达式
      • 创建一个PFEvaluator类对象,将Scanner(后缀表达式字符串)传入PFEvaluator,返回计算结果
    • evaluationStatus():

      • 获取IFToPFConverter的状态信息和PFEvaluator的状态信息并返回
  2. IFToPFConverter类

    包括构造函数,以及convert()和conversionStatus()方法:

    • 构造函数IFToPFConverter(scanner):

      • 创建operatorStack,用来存放运算符的栈
      • 保存传入的scanner
    • convert():

      • 遍历scanner中的Token
      • 返回后缀表达式的Token列表
    • conversionStatus()返回多行字符串:

      • 已经被处理的表达式字符串部分
      • 当前operatorStack上的符号
  3. PFEvaluator类

    包括构造函数,以及evaluate()和evaluationStatus()方法:

    • 构造函数PFEvaluator(scanner):

      • 创建operandStack,用来存放运算数的栈
      • 保存传入的scanner
    • evaluate():

      • 遍历scanner中的Token
      • 返回后缀表达式的计算结果
    • evaluationStatus()返回多行字符串:

      • 已经被处理的表达式字符串部分
      • 当前operandStack上的符号
  4. Scanner类

    包括构造函数,以及hasNext()和next()方法:

    • 构造函数Scanner(sourceStr):保存sourceStr字符串,用作后续扫描并提取符号(Token)
    • hasNext():如果字符串序列中还有下一个符号(Token),返回True,否则返回False
    • next():返回下一个符号(Token),如果hasNext()返回Flase了,则抛出异常。
  5. Token类

    包含两个成员变量:type和value。

    • type标识符号的类型:运算数还是运算符,以及哪种运算符,type是如下的Token类变量之一:

      UNKNOWN  = 0        # unknown
      
      INT      = 4        # integer
              
      MINUS    = 5        # minus    operator
      PLUS     = 6        # plus     operator
      MUL      = 7        # multiply operator
      DIV      = 8        # divide   operator
      LPAR     = 9        # left par operator
      RPAR     = 10       # rightpar operator
      
      
    • value保存运算符数的值,或者预算符的字符串内容。

    包含构造函数,以及getType()、getValue()和isOperator()方法:

    • 构造函数Token(value):

      • 如果value是个整数,创建个Token.INT类型的Token对象
      • 否则创建个运算符类型的Token对象(根据运算符的字符串内容创建具体的运算符Token)
    • getType():返回Token的类型

    • getValue():返回Token的值。

    • isOperator():判断Token是否为运算符。

    • getPrecedence():返回运算符的优先级。

  6. Stack类

    通用的栈容器实现,主要用到了peek()、push()和pop()方法:

    • peek():返回栈顶部的项,如果栈为空,抛出异常。
    • push(item):在栈的顶部添加一项。
    • pop():在栈的顶部删除一项并返回该项。

程序的实现

下面按照设计中类的顺序给出Python实现代码,必要的地方会给出一些解释。

  1. IFEvaluatorView类:IFEvaluatorView.py
#!/usr/bin/env python3

from IFEvaluatorModel import IFEvaluatorModel

class IFEvaluatorView:

    def run(self):
        evaluator = IFEvaluatorModel()
        while True:
            sourceStr = input("Enter an infix expression: ")
            if sourceStr == "": break
            try:
                print(evaluator.format(sourceStr))
                print(evaluator.evaluate(sourceStr))
            except Exception as e:
                print(e)
                print(evaluator.evaluationStatus())
            print()

IFEvaluatorView().run()

  1. IFEvaluatorModel类:IFEvaluatorModel.py
#!/usr/bin/env python3

from io import StringIO
from Scanner import Scanner
from PFEvaluator import PFEvaluator
from IFToPFConverter import IFToPFConverter

class IFEvaluatorModel:
   
    def evaluate(self, sourceStr):
        self.evaluator = None
        self.converter = IFToPFConverter(Scanner(sourceStr))
        postfixStr = self.converter.convert()
        self.evaluator = PFEvaluator(Scanner(postfixStr))
        value = self.evaluator.evaluate()
        return value

    def format(self, sourceStr):
        normalizedStr = ""
        scanner = Scanner(sourceStr);
        while scanner.hasNext():
            normalizedStr += str(scanner.next()) + " "
        return normalizedStr;

    def evaluationStatus(self):
        """Check to see if an evaluation has been done first."""
        result = str(self.converter)
        if self.evaluator:
            result += "\n" + str(self.evaluator)
        return result

def test_evaluator(evaluator, sourceStr):
    try:
        print(evaluator.format(sourceStr))
        print(evaluator.evaluate(sourceStr))
    except Exception as e:
        print(e)
        print(evaluator.evaluationStatus())

def main():
    # A simple tester program
    evaluator = IFEvaluatorModel()
    test_evaluator(evaluator, "8 + 2 * 3")
    test_evaluator(evaluator, "(8 + 2) * 3")
    test_evaluator(evaluator, "(8 + 2 * 3")
    test_evaluator(evaluator, "8 + 2) * 3")

if __name__ == "__main__":
    main()

  1. IFToPFConverter类:IFToPFConverter.py
#!/usr/bin/env python3

from Token import Token
from Scanner import Scanner
from Stack import Stack

class IFToPFConverter:

    def __init__(self, scanner):
        self.expressionSoFar = ""
        self.operatorStack = Stack()
        self.scanner = scanner

    def convert(self):
        postfix = list()
        while self.scanner.hasNext():
            currentToken = self.scanner.next()
            self.expressionSoFar += str(currentToken) + " "
            if currentToken.getType() == Token.UNKNOWN:
                raise AttributeError("Unrecognized symbol")
            if currentToken.getType() == Token.INT:
                postfix.append(str(currentToken))
            elif currentToken.getType() == Token.LPAR:
                self.operatorStack.push(currentToken)
            elif currentToken.getType() == Token.RPAR:
                if self.operatorStack.isEmpty():
                    raise AttributeError("Too few operators(No matching opening left parenthese found)")
                topOperator = self.operatorStack.pop()
                while topOperator.getType() != Token.LPAR:
                    postfix.append(str(topOperator))
                    if self.operatorStack.isEmpty():
                        raise AttributeError("Too few operators(No matching opening left parenthese found)")
                    topOperator = self.operatorStack.pop()
            else:
                while not self.operatorStack.isEmpty() and \
                      self.operatorStack.peek().getPrecedence() >= currentToken.getPrecedence():
                    postfix.append(str(self.operatorStack.pop()))
                self.operatorStack.push(currentToken)
        while not self.operatorStack.isEmpty():
            if self.operatorStack.peek().getType() == Token.LPAR:
                raise AttributeError("Too few operators(No matching opening right parenthese found)")
            postfix.append(str(self.operatorStack.pop()))
        return " ".join(postfix)
   
    def __str__(self):
        result = ""
        if self.expressionSoFar == "":
            result += "Portion of infix expression processed: none\n"
        else: 
            result += "Portion of infix expression processed: " + \
                   self.expressionSoFar + "\n"
        if self.operatorStack.isEmpty():
            result += "The stack is empty"
        else:
            result += "Operators on the stack          : " + \
                      str(self.operatorStack)
        return result

    def conversionStatus(self):
        return str(self)

    
def main():
    while True:
        sourceStr = input("Enter an infix expression: ")
        if sourceStr == "":
            break
        else:
            try:
                converter = IFToPFConverter(Scanner(sourceStr))
                print("Postfix:", converter.convert())
            except Exception as e:
                print(e)
                print(converter.conversionStatus())

if __name__ == "__main__":
    main()

IFToPFConverter.convert()函数的具体步骤如下:

  1. 开始的时候,有一个空的后缀表达式(postfix)和一个空的栈(operatorStack),栈用来保存运算符和左括号。
  2. 从左向右扫描中缀表达式。
  3. 遇到一个运算数的时候,将其添加到后缀表达式的后面。
  4. 遇到一个左括号的时候,将其压入到栈中。
  5. 遇到一个运算符,从栈中弹出和它具有相等的或更高优先级的所有运算符,将它们添加到后缀表达式的末尾,然后,将扫描到的运算符压入到栈中。
  6. 遇到一个右括号的时候,将运算符从栈中移动到后缀表达式中,直到遇到了与之匹配的左括号,并将其丢弃。
  7. 遇到中缀表达式结束的时候,将栈中剩下的运算符都转移到后缀表达式之中。

表7.6和表7.7举例说明了这个过程。

table-7-6.png

table-7-7.png

  1. PFEvaluator类:PFEvaluator.py
#!/usr/bin/env python3

from Token import Token
from Scanner import Scanner
from Stack import Stack

class PFEvaluator:
   
    def __init__(self, scanner):
        self.expressionSoFar = ""
        self.operandStack = Stack()
        self.scanner = scanner

    def evaluate(self):
        while self.scanner.hasNext():
            currentToken = self.scanner.next()
            self.expressionSoFar += str(currentToken) + " "
            if currentToken.getType() == Token.INT:
                self.operandStack.push(currentToken)
            elif currentToken.isOperator(): 
                if len(self.operandStack) < 2:
                    raise AttributeError("Too few operands on the stack")
                t2 = self.operandStack.pop()
                t1 = self.operandStack.pop()
                result = Token(self.computeValue(currentToken,
                                                 t1.getValue(),
                                                 t2.getValue()))
                self.operandStack.push(result)

            else:
                raise AttributeError("Unknown token type")
        if len(self.operandStack) > 1:
            raise AttributeError("Too many operands on the stack")
        result = self.operandStack.pop()
        return result.getValue();   

    def __str__(self):
        result = ""
        if self.expressionSoFar == "":
            result += "Portion of postfix expression processed: none\n"
        else: 
            result += "Portion of postfix expression processed: " + \
                   self.expressionSoFar + "\n"
        if self.operandStack.isEmpty():
            result += "The stack is empty"
        else:
            result += "Operands on the stack          : " + \
                      str(self.operandStack)
        return result

    def evaluationStatus(self):
        return str(self)

    def computeValue(self, op, value1, value2):
        result = 0;
        theType = op.getType()
        if theType == Token.PLUS:
            result = value1 + value2;
        elif theType == Token.MINUS:
            result = value1 - value2;
        elif theType == Token.MUL:
            result = value1 * value2;
        elif theType == Token.DIV:
            result = value1 // value2;
        else:
            raise Exception("Unknown operator")
        return result

def main():
    while True:
        sourceStr = input("Enter a postfix expression: ")
        if sourceStr == "":
            break
        else:
            try:
                evaluator = PFEvaluator(Scanner(sourceStr))
                print("Result:", evaluator.evaluate())
            except Exception as e:
                print(e)
                print(evaluator.evaluationStatus())

if __name__ == "__main__":
    main()

PFEvaluator.evaluate()函数的具体步骤如下:

  1. 开始的时候,有一个空的栈(operandStack),栈用来保存运算数和运算结果。
  2. 从左向右扫描后缀表达式。
  3. 遇到一个运算数的时候,将其压入到栈中。
  4. 遇到一个运算符的时候,从栈中弹出两个运算数,并且对这两个运算数应用该运算符,并且将结果压入栈中。
  5. 继续遍历,直到到达了表达式的末尾,此时,只剩下表达式的值。

表7.5举例说明了这个过程。

table-7-7.png

  1. Scanner类:Scanner.py
#!/usr/bin/env python3

from Token import Token

class Scanner:

    EOE = ';'        # end-of-expression
    TAB = '\t'       # tab

    def __init__(self, sourceStr):
        self.sourceStr = sourceStr
        self.getFirstToken()

    def hasNext(self):
        return self.currentToken != None

    def next(self):
        if not self.hasNext():
            raise Exception("There are no more tokens")           
        temp = self.currentToken
        self.getNextToken()
        return temp

    def getFirstToken(self):
        self.index = 0
        self.currentChar = self.sourceStr[0]
        self.getNextToken()
    
    def getNextToken(self):
        self.skipWhiteSpace()
        if self.currentChar.isdigit():
            self.currentToken = Token(self.getInteger())
        elif self.currentChar == Scanner.EOE:
            self.currentToken = None
        else:
            self.currentToken = Token(self.currentChar)
            self.nextChar()
    
    def nextChar(self):
        if self.index >= len(self.sourceStr) - 1:
            self.currentChar = Scanner.EOE
        else:
            self.index += 1
            self.currentChar = self.sourceStr[self.index]
    
    def skipWhiteSpace(self):
        while self.currentChar in (' ', Scanner.TAB):
            self.nextChar()
    
    def getInteger(self):
        num = 0
        while True:
            num = num * 10 + int(self.currentChar)
            self.nextChar()
            if not self.currentChar.isdigit():
                break
        return num

def main():
    # A simple tester program
    while True:
        sourceStr = input("Enter an expression: ")
        if sourceStr == "": break
        scanner = Scanner(sourceStr)
        while scanner.hasNext():
            print(scanner.next())

if __name__ == '__main__': 
    main()

  1. Token类:Token.py
#!/usr/bin/env python3

class Token:

    UNKNOWN  = 0        # unknown
    
    INT      = 4        # integer
            
    MINUS    = 5        # minus    operator
    PLUS     = 6        # plus     operator
    MUL      = 7        # multiply operator
    DIV      = 8        # divide   operator
    LPAR     = 9        # left par operator
    RPAR     = 10       # rightpar operator

    FIRST_OP = 5        # first operator code

    def __init__(self, value):
        if type(value) == int:
            self.type = Token.INT
        else:
            self.type = self.makeType(value)
        self.value = value

    def isOperator(self):
        return self.type >= Token.FIRST_OP

    def __str__(self):
        return str(self.value)
    
    def getType(self):
       return self.type
    
    def getValue(self):
       return self.value

    def makeType(self, ch):
        if   ch == '*': return Token.MUL
        elif ch == '/': return Token.DIV
        elif ch == '+': return Token.PLUS
        elif ch == '-': return Token.MINUS
        elif ch == '(': return Token.LPAR
        elif ch == ')': return Token.RPAR
        else:           return Token.UNKNOWN

    def getPrecedence(self):
        """Returns the precedunce level of an operator."""
        myType = self.type
        if myType in (Token.MUL, Token.DIV):
            return 2
        elif myType in (Token.PLUS, Token.MINUS):
            return 1
        else:
            return 0

def main():
    # A simple tester program
    plus = Token("+")
    minus = Token("-")
    mul = Token("*")
    div = Token("/")
    unknown = Token("#")
    anInt = Token(34)
    print(plus, minus, mul, div, unknown, anInt)

if __name__ == '__main__': 
    main()

  1. Stack类:Stack.py
class Stack:
    def __init__(self):
        self.items = list()

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

    def __str__(self):
        return "[" + ", ".join(map(str, self.items)) + "]"

    def __iter__(self):
        return iter(self.items)

    def isEmpty(self):
        return len(self.items) == 0

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

    def pop(self):
        if self.isEmpty():
            raise KeyError("The stack is empty")
        return self.items.pop()

    def peek(self):
        if self.isEmpty():
            raise KeyError("The stack is empty")
        return self.items[-1]

    def clear(self):
        self.items = list()

Stack类就是简单地对列表类的封装。

关于Python学习指南

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码免费领取保证100%免费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1620129.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

碰到今日伦敦银价格走势图不懂得分析怎么办?

踏入2024年&#xff0c;伦敦银出现了比往年更多的投资机会&#xff0c;尤其是近期伦敦银价格连续上涨突破多个整数关口&#xff0c;现在已经站在28上方。碰到这么强的走势&#xff0c;投资者自然很想快点入场交易。但是交易前投资者需要分析今日伦敦银价格走势图之后再入场&…

ffmpeg支持MP3编码的方法

目录 现象 解决办法 如果有编译包没有链接上的情况 现象 解决办法 在ffmpeg安装包目录下 &#xff0c;通过./configure --list-encoders 和 ./configure --list-decoders 命令可以看到&#xff0c;ffmpeg只支持mp3解码&#xff0c;但是不支持mp3编码。 上网查寻后发现&…

idm序列号永久激活码2023免费可用 IDM软件破解版下载 最新版Internet Download Manager 网络下载加速必备神器 IDM设置中文

IDM是一款多线程下载工具&#xff0c;全称Internet Download Manager。IDM的多线程加速功能&#xff0c;能够充分利用宽带&#xff0c;所以下载速度会比较快&#xff0c;而且它支持断点续传。它的网站音视频捕获、站点抓取、静默下载等功能&#xff0c;也特别实用。 idm使用技…

SS34B-ASEMI超低Low VF肖特基SS34B

编辑&#xff1a;ll SS34B-ASEMI超低Low VF肖特基SS34B 型号&#xff1a;SS34B 品牌&#xff1a;ASEMI 封装&#xff1a;SMB 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;3A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;40V 最大正向电压…

hyperf 三十一 极简DB组件

一 安装及配置 composer require hyperf/db php bin/hyperf.php vendor:publish hyperf/db 默认配置 config/autoload/db.php 如下&#xff0c;数据库支持多库配置&#xff0c;默认为 default。 配置项类型默认值备注driverstring无数据库引擎 支持 pdo 和 mysqlhoststringl…

线程安全以及解决方案

文章目录 1.线程安全的原因①抢占式执行②多线程修改同一个变量③修改的操作不是原子的④内存可见性⑤指令重排序 2. 线程安全的解决方案3 synchronized的特性------可重入锁 1.线程安全的原因 ①抢占式执行 操作系统对线程的调度是随机的&#xff0c;没有规律&#xff08;主…

什么便签好用又没广告 好用无广便签分享

身处这个快节奏的时代&#xff0c;我们时常被各种琐事和计划所包围。想象一下&#xff0c;你在办公桌前&#xff0c;电脑屏幕上杂乱无章地贴着各种纸质便签&#xff0c;有的记录着待办事项&#xff0c;有的则是灵感闪现时的几句诗句。每次想要查找某个信息&#xff0c;都得费力…

Golang | Leetcode Golang题解之第42题接雨水

题目&#xff1a; 题解: func trap(height []int) (ans int) {n : len(height)if n 0 {return}leftMax : make([]int, n)leftMax[0] height[0]for i : 1; i < n; i {leftMax[i] max(leftMax[i-1], height[i])}rightMax : make([]int, n)rightMax[n-1] height[n-1]for i…

CANoe-Vector Security Manager介绍

Vector Security Manager 是 Vector 公司提供的一种工具,它为像 CANoe 这样的 Vector 工具提供安全功能,例如安全相关的通信(SecOC)、诊断、认证等,这些功能都是在安全配置文件中进行管理的。所有支持的工具都采用统一的配置方式。 一个安全配置文件为工具提供了以下安全…

探索AI时代的新天地:LLAMA3引领人工智能革命

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

如何安全高效地进行网点文件下发?

随着IT技术的飞速发展&#xff0c;以银行为代表的企业数字化技术转型带来了大量的电子化文档传输需求。文件传输数量呈几何级数增长&#xff0c;传统集中式文件传输模式在爆炸式的增长需求下&#xff0c;银行网点文件下发的效率、可靠性、安全性等方面&#xff0c;都需要重点关…

边缘计算的优势

边缘计算的优势 边缘计算是一种在数据生成地点附近处理数据的技术&#xff0c;而非传统的将数据发送到远端数据中心或云进行处理。这种计算模式对于需要快速响应的场景特别有效&#xff0c;以下详述了边缘计算的核心优势。 1. 降低延迟 边缘计算通过在数据源近处处理数据&…

2款摄像头录像软件,满足你的多种要求!

“有没有一款能够录制摄像头视频的软件呀&#xff1f;我计划录制一些生活小窍门和教学视频&#xff0c;想要能清楚地拍到自己的操作过程。但找了好多软件&#xff0c;都不太满意&#xff0c;真心希望大家能给我推荐几款好用的摄像头录像软件&#xff0c;最好能简单易上手的&…

GPU功能介绍简介

GPU功能介绍简介 随着计算需求的不断升级&#xff0c;尤其是在图形密集型和并行计算任务中&#xff0c;GPU已经从一个简单的图像渲染器件演变成一个强大的计算工具。本篇文章将深入探讨GPU的核心功能、架构以及其在多个领域中的应用。 一、GPU的起源与演进 GPU最初设计用于加速…

百兆集成网络链接器911105A

百兆集成网络链接器&#xff08;有时也称为百兆网卡&#xff09;是一种硬件设备&#xff0c;主要用于计算机与计算机网络之间的高速数据传输。它的主要功能包括&#xff1a; 1. 高速数据传输&#xff1a;百兆集成网络链接器支持100Mbps的数据传输速率&#xff0c;比之前的以太…

抖音老阳讲的选品师项目普通人能赚钱吗?

随着互联网的快速发展&#xff0c;电商行业也迎来了前所未有的繁荣。在这个背景下&#xff0c;选品师这一职业逐渐走进人们的视野。老阳作为行业内的知名人士&#xff0c;经常分享选品师的经验和项目。那么&#xff0c;普通人能否参与老阳讲的选品师项目并且赚钱吗?答案是肯定…

护眼台灯有辐射吗?曝光护眼台灯四大套路!

护眼台灯能够提供便利、健康的光线环境&#xff0c;但作为光学测评师&#xff0c;我观察到一些低品质的护眼台灯存在重大的隐患&#xff0c;这些由劣质材料生产而成的护眼台灯&#xff0c;在使用的过程中&#xff0c;有可能会释放对人体视力有害的辐射&#xff0c;甚至会导致黄…

idea插件快速搜索接口位置之RestfulTool平替Apipost-Helper-2.​0

需求 经常需要根据请求路径搜索某接口位置&#xff0c;特点是接口没有斜杠\&#xff0c;所以双击Shrift找不到接口 RestfulTool 和 RestfulToolkit-fix平替 这两个插件在idea2023.3中无法使用&#xff0c;使用的是Apipost-Helper-2.​0来代替&#xff0c;他也有自己的快捷键…

风险防不胜防?看YashanDB如何守护你的数据库安全(上篇)

数据库作为信息系统的核心&#xff0c;不仅承载着海量的关键数据&#xff0c;还负责向各类用户提供高效、可靠的信息服务&#xff0c;数据库的安全性显得尤为关键&#xff0c;已成为信息安全体系的重中之重。 什么是数据库安全&#xff1f; 数据库安全是数据安全的一个子集&a…

第9章:知识生成提示

知识生成提示&#xff0c;是告诉ChatGPT创造新信息的命令。 你可以告诉它&#xff1a;请生成关于【X】 的新信息。ChatGPT会利用已有知识生成内容。 你也可以同时提出具体要求&#xff0c;如内容类型、长度和风格等。 例1:知识生成 任务: 生成有关特定主题的新信息。指令: 生…