带括号的四则运算表达式的求值栈实现

合集下载

栈的实验报告结论(3篇)

栈的实验报告结论(3篇)

第1篇一、实验目的1. 理解栈的基本概念和操作;2. 掌握栈的顺序存储和链式存储实现方法;3. 熟悉栈在程序设计中的应用。

二、实验内容1. 栈的顺序存储结构实现;2. 栈的链式存储结构实现;3. 栈的基本操作(入栈、出栈、判空、求栈顶元素);4. 栈在程序设计中的应用。

三、实验方法1. 采用C语言进行编程实现;2. 对实验内容进行逐步分析,编写相应的函数和程序代码;3. 通过运行程序验证实验结果。

四、实验步骤1. 实现栈的顺序存储结构;(1)定义栈的结构体;(2)编写初始化栈的函数;(3)编写入栈、出栈、判空、求栈顶元素的函数;(4)编写测试程序,验证顺序存储结构的栈操作。

2. 实现栈的链式存储结构;(1)定义栈的节点结构体;(2)编写初始化栈的函数;(3)编写入栈、出栈、判空、求栈顶元素的函数;(4)编写测试程序,验证链式存储结构的栈操作。

3. 栈在程序设计中的应用;(1)实现一个简单的四则运算器,使用栈进行运算符和操作数的存储;(2)实现一个逆序输出字符串的程序,使用栈进行字符的存储和输出;(3)编写测试程序,验证栈在程序设计中的应用。

五、实验结果与分析1. 顺序存储结构的栈操作实验结果:(1)入栈操作:在栈未满的情况下,入栈操作成功,栈顶元素增加;(2)出栈操作:在栈非空的情况下,出栈操作成功,栈顶元素减少;(3)判空操作:栈为空时,判空操作返回真,栈非空时返回假;(4)求栈顶元素操作:在栈非空的情况下,成功获取栈顶元素。

2. 链式存储结构的栈操作实验结果:(1)入栈操作:在栈未满的情况下,入栈操作成功,链表头指针指向新节点;(2)出栈操作:在栈非空的情况下,出栈操作成功,链表头指针指向下一个节点;(3)判空操作:栈为空时,判空操作返回真,栈非空时返回假;(4)求栈顶元素操作:在栈非空的情况下,成功获取栈顶元素。

3. 栈在程序设计中的应用实验结果:(1)四则运算器:成功实现加、减、乘、除运算,并输出结果;(2)逆序输出字符串:成功将字符串逆序输出;(3)测试程序:验证了栈在程序设计中的应用。

栈实现计算器(简单四则运算)

栈实现计算器(简单四则运算)

栈实现计算器(简单四则运算)主要是通过定义⼀个数栈和⼀个符号栈,并根据给出的计算式进⾏拆分,循环判断是数字还是符号,考虑数字的连续性和符号计算的优先级,具体实现如下:package com.pangzi.stucture;public class calculator {public static void main(String[] args) {String expression = "50+9*9-7";//定义⼀个需要被扫描的表达式//创建两个栈,⼀个数栈,⼀个符号栈ArrayStack2 numStack = new ArrayStack2(10);ArrayStack2 operStack = new ArrayStack2(10);//定义需要的变量int index = 0;//定义⼀个指向数字和运算符的索引,扫描栈中的内容int num1 = 0;//定义第⼀个数字int num2 = 0;//定义第⼆个数字int oper = 0;//定义操作符int res = 0;//定义运算结果char ch = ' ';//将每次扫描得到的char保存⾄ch⾥⾯String keepNum = "";//⽤于拼接多位数//开始扫描表达式while(true){//依次得到expression中的每⼀个字符ch = expression.substring(index, index+1).charAt(0);//⽤substr获取长度为1的⼀个个字符串,然后通过charat转换为字符。

//判断字符是数字还是运算符,然后进⾏处理if(operStack.isOper(ch)){//如果ch是⼀个符号//判断符号栈是否为空if(!operStack.isEmpty()){//如果符号栈不为空,⽤ch和符号栈存在的运算符进⾏⽐较,如果ch的优先级⼩于等于栈中符号的优先级//就从数栈中弹出两个数字,进⾏运算并将得到的结果放⼊数栈,然后将ch⼊符号栈if(operStack.priority(ch) <= operStack.priority(operStack.peek())){num1 = numStack.pop();num2 = numStack.pop();oper = operStack.pop();res = numStack.cal(num1, num2, oper);numStack.push(res);operStack.push(ch);}else{//如果当前操作符的优先级⼤于符号栈中的优先级,直接⼊符号栈operStack.push(ch);}}else{//如果符号栈为空,进⾏⼊栈操作operStack.push(ch);//将ch⼊符号栈}}else{//如果ch是数据的话,则直接⼊数栈//numStack.push(ch - 48);//根据ascii表换算//当处理多位数时,不能扫描到数字时就⽴即⼊栈,因为有可能是多位数//在处理时,应该在expression的表达式后⾯在扫描⼀位,如果是数继续扫描,如果是符合则停⽌。

表达式求值实验报告

表达式求值实验报告

表达式求值的类型定义与操作实现一、需求分析设计一个程序,演示用算符优先法对算术表达式求值的过程。

利用算符优先关系,实现对算术四则混合运算表达式的求值。

(1)输入的形式:表达式,例如2*(3+4)#;包含的运算符只能有'+' 、'-' 、'*' 、'/' 、'('、')';(2)输出的形式:运算结果,例如Answer is:77.000000;(3)程序所能达到的功能:对表达式求值并输出结果。

二、概要设计:本课程设计需要用到抽象数据类型栈存储表达式。

本部分给出栈的类型定义与表达式求值操作描述。

1、存储结构(顺序栈):typedef struct SqStack{SElemType *base;SElemType *top;int stacksize;}SqStack;2、基本操作:Status InitStack(SqStack &s)操作结果:初始化一个空栈s。

Status GetTop(SqStack s,SElemType &e)初始条件:栈s已存在。

操作结果:得到s的栈顶元素并用e带回。

Status Push(SqStack &s,SElemType e)初始条件:栈s已存在。

操作结果:向栈s中压入元素e。

Status Pop(SqStack &s,SElemType &e)初始条件:栈s已存在‘操作结果:弹出栈s栈顶元素,并用e带回。

Status In(char e)操作结果:判断e是否为7种运算符之一char Precede(char p,char c)操作结果:比较运算符p与运算符c的优先级。

SElemType Operate(SElemType x,char n,SElemType y)操作结果:计算x,y对运算符n的运算结果。

三、详细设计本部分主要给出表达式求值的实现算法1、初始化一个空栈sStatus InitStack(SqStack &s) //{s.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!s.base)exit(OVERFLOW);s.top=s.base;s.stacksize=STACK_INIT_SIZE;return OK;}2、读取栈顶元素Status GetTop(SqStack s,SElemType &e){if(s.top==s.base)return ERROR;e=*(s.top-1);return OK;}3、向栈s中压入元素eStatus Push(SqStack &s,SElemType e){if(s.top-s.base>=s.stacksize){s.base=(SElemType*)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));if(!s.base)exit(OVERFLOW);s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;return OK;}4、弹出栈顶元素Status Pop(SqStack &s,SElemType &e) //{if(s.top==s.base)exit(OVERFLOW);e=* --s.top;return OK;}5、判断是否为7种运算符之一Status In(char e) / /{switch(e){case '+':case '-':case '*':case '/':case '(':case ')':case '#':return(1);break;default:return(0);}}6、比较两运算符优先级char Precede(char p,char c){ 'switch(p){case '+':case '-':switch(c){case '*':case '/':case '(':return '<';break;default:return '>';break;}break;case '*':case '/':switch(c){case '(':return '<';break;default:return '>';break;}break;case '(':switch(c){case ')':return '=';break;case '#':printf("ERROR!!\n");exit(OK);default:return '<';break;}break;case ')':switch(c){case '(':printf("ERROR!!\n");exit(OK);default:return '>';break;}break;case '#':switch(c){case ')':printf("ERROR!!\n");exit(OK);case '#':return '=';break;default:return '<';break;}break;}}7、四则运算SElemType Operate(SElemType x,char n,SElemType y) {SElemType e;switch(n){case '+':e=x+y;break;case '-':e=x-y;break;case '*':e=x*y;break;case '/':if(y==0){printf("分母不能为0!\n");exit(1);}else{e=x/y;break;}}return e;}8、主函数进行表达式求值void main(){SqStack OPTR,OPND;SElemType p,s,a,b,theta;char c;printf("请输入一个表达式并以'#'结束\n(只包括' +-*/' 和'('')'):\n");InitStack(OPTR);Push(OPTR,'#');InitStack(OPND);c=getchar();GetTop(OPTR,p);while(c!='#'||p!='#'){if(!In(c)){s=c-48;c=getchar();while(c>='0'&&c<='9'){s=s*10+(c-48);c=getchar();}Push(OPND,s);}else{switch(Precede(p,c)){case '<':Push(OPTR,c);c=getchar();break;case '=':Pop(OPTR,s);c=getchar();break;case '>':Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}GetTop(OPTR,p);}}//whileprintf("\n\n");GetTop(OPND,p);printf("Answer is:%f\n",p);getch();}四、调试分析1、初始化了一种类型的两个栈,分别用来存放数值和运算符。

带有括号的四则运算

带有括号的四则运算

带有括号的四则运算四则运算是我们日常生活和学习中经常要进行的计算方法,而带有括号的四则运算则是其中的一种特殊情况。

在这篇文章中,我将为您详细介绍带有括号的四则运算,并给出一些例子来帮助您更好地理解。

1. 括号的作用在四则运算中,括号有着非常重要的作用,它可以改变运算的优先级。

在没有括号的情况下,我们通常按照“先乘除后加减”的顺序进行计算,但当出现括号时,我们需要先计算括号内的运算。

括号将其中的表达式视为一个整体,先进行括号内的运算,再根据整体的结果进行后续的运算。

2. 加法和减法运算中的括号在加法和减法运算中,括号的作用主要是改变运算的顺序。

括号内的运算优先于括号外的运算,在计算时,我们需要先计算括号内的表达式,然后再将括号外的部分与括号内的结果进行运算。

例如:2 + (3 - 1) = 2 + 2 = 4在这个例子中,括号内的运算3 - 1先进行,得到结果2,然后与括号外的2进行加法运算得到最终结果4。

3. 乘法和除法运算中的括号在乘法和除法运算中,括号同样有着重要的作用。

括号内的表达式会先进行计算,然后将结果作为乘法或除法运算的因子进行运算。

例如:2 * (3 + 4) = 2 * 7 = 14在这个例子中,括号内的运算3 + 4先进行,得到结果7,然后与括号外的2进行乘法运算得到最终结果14。

4. 混合运算中的括号在实际的四则运算中,我们往往会出现多个括号同时存在的情况。

这时,我们需要根据括号的嵌套关系,先计算最内层的括号内的运算,逐层向外进行,直到计算出整个表达式的结果。

例如:2 * (3 + 4) - (5 - 1) = 2 * 7 -4 = 10在这个例子中,先计算括号内的运算3 + 4得到结果7,然后计算括号内的运算5 - 1得到结果4,最后将括号外的2 * 7与4进行减法运算得到最终结果10。

这个过程中,我们按照括号嵌套的顺序进行计算,确保计算的准确性。

需要注意的是,括号的使用能够清晰地表达我们想要进行的运算顺序,但在实际计算中,我们也可以根据数学运算的优先级来进行运算,而不仅仅依赖于括号。

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法

利用栈来实现算术表达式求值的算法利用栈来实现算术表达式求值的算法算术表达式是指按照一定规则组成的运算式,包含数字、运算符和括号。

在计算机中,求解算术表达式是一项基本的数学运算任务。

根据算术表达式的性质,我们可以考虑利用栈这一数据结构来实现求值算法。

一、算法思路首先,我们需要明确一个重要概念——逆波兰表达式(ReversePolish notation)。

逆波兰表达式是一种没有括号的算术表达式,其运算规则是先计算后面的数字和运算符,再计算前面的数字和运算符。

例如,对于算术表达式“3+4*5-6”,其对应的逆波兰表达式为“3 45 * +6 -”。

那么,我们可以利用栈来实现将中缀表达式转化为逆波兰表达式的过程,具体步骤如下:1. 创建两个栈——操作数栈和操作符栈。

2. 从左到右扫描中缀表达式的每一个数字和运算符,遇到数字则压入操作数栈中,遇到运算符则进行如下操作:(1)如果操作符栈为空或当前运算符的优先级大于栈顶运算符的优先级,则将当前运算符压入操作符栈中。

(2)如果当前运算符的优先级小于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入操作数栈中,重复此过程直到遇到优先级较低的运算符或操作符栈为空为止,然后将当前运算符压入操作符栈中。

3. 扫描完中缀表达式后,若操作符栈不为空,则将其中所有运算符弹出并加入操作数栈中。

4. 最终,操作数栈中存放的就是逆波兰表达式,我们可以按照逆波兰表达式的计算规则来计算其结果。

二、算法优点利用栈来实现算术表达式求值的算法具有以下优点:1. 代码简洁易懂,易于实现和维护。

2. 由于将中缀表达式转化为逆波兰表达式后,可以减少运算符的优先级关系而消除括号,从而减少求值的复杂度,提高程序的执行效率。

三、代码实现下面是利用栈来实现算术表达式求值的算法的Python代码实现:```pythonclass Stack:def __init__(self):self.items = []def push(self, item):self.items.append(item)def pop(self):return self.items.pop()def peek(self):return self.items[-1]def is_empty(self):return len(self.items) == 0def size(self):return len(self.items)def calculate(op_num1, op_num2, operator):if operator == "+":return op_num1 + op_num2elif operator == "-":return op_num1 - op_num2elif operator == "*":return op_num1 * op_num2elif operator == "/":return op_num1 / op_num2def infix_to_postfix(infix_expr):opstack = Stack()postfix_expr = []prec = {"+": 1, "-": 1, "*": 2, "/": 2, "(": 0} token_list = infix_expr.split()for token in token_list:if token.isdigit():postfix_expr.append(token)elif token == '(':opstack.push(token)elif token == ')':top_token = opstack.pop()while top_token != '(':postfix_expr.append(top_token)top_token = opstack.pop()else:while (not opstack.is_empty()) and(prec[opstack.peek()] >= prec[token]):postfix_expr.append(opstack.pop())opstack.push(token)while not opstack.is_empty():postfix_expr.append(opstack.pop())return " ".join(postfix_expr)def postfix_eval(postfix_expr):opstack = Stack()token_list = postfix_expr.split()for token in token_list:if token.isdigit():opstack.push(int(token))else:op_num2 = opstack.pop()op_num1 = opstack.pop()result = calculate(op_num1, op_num2, token) opstack.push(result)return opstack.pop()infix_expr = "3 + 4 * 5 - 6"postfix_expr = infix_to_postfix(infix_expr)print(postfix_expr)print(postfix_eval(postfix_expr))```四、总结算术表达式求值是一项常见的数学运算任务,利用栈这一数据结构来实现求值算法是一种简单有效的方法,它将中缀表达式转化为逆波兰表达式后,可以消除括号并减少运算符的优先级关系,从而提高程序的执行效率。

栈实现四则运算

栈实现四则运算

栈实现四则运算休息一会儿。

来恒为的第三天了,到目前为止做的事情就是把四则运算的栈实现完成的差不多了,说差不多是因为对输入会出错的判断和输出还没有实现。

来说说这个程序吧。

首先,对输入的表达式是以字符为单位读入的,对每个读入的字符进行判断,数字放到character栈中,算符放到operator栈中,另外定义了push和pop的函数进行进栈和出栈的操作,(大二学数据结构的时候对各种结构一直没有清晰的认识,现在觉得结构的特性取决于对结构的操作,也就是他的行为决定了他的特性,然后才有栈,队列等名字)。

初始化的时候先将‘#’字符压到operator栈中,此时其优先级是最低的,方便对以后读入的算符进行比较和处理。

优先级的判断是通过定义了两个数组实现的。

当后来读入的算符的优先级低于已经在operator中栈顶的算符时就弹出operator中的算符以及character中的两个数字用operate函数进行运算,运算的数值push 到character栈中,继续进行算符的判断看是否需要继续进行运算。

表达式必须是以‘#’结尾的,当operator中的栈顶和最后读入的字符都是‘#’时就结束循环,返回character中栈顶元素,这就是最后的结果。

整体的思路就是对输入表达式的依次读入和处理,对一开始就出现的‘+’和‘-’要进行特殊的处理,设置一个标志位对负数进行标记,正数直接覆盖。

由于是一位一位读取的,对多位数的处理要用求和的方式。

难点是对运算符优先级的判断,特别是括号的处理,这也是我觉得最为巧妙的地方。

设置两个整型数组,分别对应栈内和栈外的算符优先级。

对括号的处理上,栈外的‘)’应该与栈内的‘(’优先级相同,把两者之间的运算解决之后要将栈内的‘(’pop出来,以免影响后续的操作。

清单:mystack栈,in[7],out[7]优先级数组,ch[7]保存算符对应的数字。

函数:push,pop,gettop,initstack,compare,evaluate对输入格式的错误处理还没有具体实现。

栈的应用——表达式求值

栈的应用——表达式求值

栈的应⽤——表达式求值 表达式求值是程序设计语⾔编译中的⼀个基本问题,它的实现就是对“栈”的典型应⽤。

本⽂针对表达式求值使⽤的是最简单直观的算法“算符优先法”。

本⽂给出两种⽅式来实现表达式求值,⽅式⼀直接利⽤中缀表达式求值,需要⽤到两个栈,操作数栈和操作符栈。

⾸先置操作数栈为空栈,操作符栈仅有“#”⼀个元素。

依次读⼊表达式中的每个字符,若是操作数则进操作数栈,若是操作符则和操作符栈的栈顶运算符⽐较优先权作相应操作,直⾄整个表达式求值完毕。

⽅式⼆⾸先把中缀表达式转换为后缀表达式并存储起来,然后利⽤读出的后缀表达式完成求值,其本质上是⽅式⼀的分解过程。

表达式求值的代码如下:#include <iostream>#include "stack"#include "map"using namespace std;/* 只能求⼀位整数的加减乘除混合运算 */map<char, pair<int, int>> priority; // 存放各个操作符的栈内栈外优先级,first是栈内,second是栈外char infix[50]; // 存放初始的中缀表达式char postfix[50]; // 存放转化的后缀表达式int result;void MakePriority() // 构造运算符优先级表{priority.insert(make_pair('#', make_pair(0, 0))); // isp(#)=0, icp(#)=0priority.insert(make_pair('\n', make_pair(0, 0))); // isp(\n)=0, icp(\n)=0 表达式结尾的'#'⽤'\n'代替,这样可以省略表达式末尾的结束符'#'priority.insert(make_pair('(', make_pair(1, 6))); // isp(()=1, icp(()=6priority.insert(make_pair('*', make_pair(5, 4))); // isp(*)=5, icp(*)=4priority.insert(make_pair('/', make_pair(5, 4))); // isp(/)=5, icp(/)=4priority.insert(make_pair('%', make_pair(5, 4))); // isp(%)=5, icp(%)=4priority.insert(make_pair('+', make_pair(3, 2))); // isp(+)=3, icp(+)=2priority.insert(make_pair('-', make_pair(3, 2))); // isp(-)=3, icp(-)=2priority.insert(make_pair(')', make_pair(6, 1))); // isp())=6, icp())=1}void InfixToPostfix() // 把中缀表达式转换为后缀表达式{int i = 0;stack<char> optrStack; // 操作符栈char optr; // optr为栈顶的操作符optrStack.push('#');while (!optrStack.empty()){if (isdigit(infix[i])) // 是操作数则直接输出(追加到postfix结尾){postfix[strlen(postfix)] = infix[i];postfix[strlen(postfix) + 1] = '\0';i++; // 读⼊中缀表达式的下⼀个字符}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出栈顶操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈{optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first)// icp(infix[i]) < isp(optr),optr退栈并输出{postfix[strlen(postfix)] = optr;postfix[strlen(postfix) + 1] = '\0';optrStack.pop();}else// icp(infix[i]) = isp(optr),退栈但不输出,若退出的是'(',则继续读⼊下⼀个字符{optrStack.pop();if (optr == '(')i++;}}}}void CalculateByPostfix() // 通过后缀表达式求值{int i = 0;stack<int> opndStack; // 操作数栈int left, right; // 左右操作数int value; // 中间结果int newOpnd;while (postfix[i] != '#' && i < strlen(postfix)){switch (postfix[i]){case'+':right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left - right;opndStack.push(value);break;case'*':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();value = left * right;opndStack.push(value);break;case'/':right = opndStack.top();opndStack.pop();left = opndStack.top();opndStack.pop();if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:newOpnd = (int)(postfix[i] - 48); // 操作数直接⼊栈opndStack.push(newOpnd);break;}i++;}result = opndStack.top();}void CalculateByInfix() // 直接利⽤中缀表达式求值{int i = 0;stack<char> optrStack; // 操作符栈stack<int> opndStack; // 操作数栈char optr; // optr为操作符栈顶的操作符int left, right, value; // 左右操作数以及中间结果optrStack.push('#');optr = optrStack.top();while (!optrStack.empty()) // 直到操作符栈为空{if (isdigit(infix[i])) // 是操作数, 进操作数栈{value = (int)(infix[i] - 48);opndStack.push(value);i++;}else// 是操作符, ⽐较优先级{optr = optrStack.top(); // 取出操作符栈顶的操作符if (priority[infix[i]].second > priority[optr].first) // icp(infix[i]) > isp(optr),infix[i]⼊栈 {optrStack.push(infix[i]);i++;}else if (priority[infix[i]].second < priority[optr].first) // icp(infix[i]) < isp(optr),optr退栈并输出{optrStack.pop();right = opndStack.top(); // 从操作数栈中取出两个操作数opndStack.pop();left = opndStack.top();opndStack.pop();switch (optr){case'+':value = left + right;opndStack.push(value); // 中间结果⼊栈break;case'-':value = left - right;opndStack.push(value); // 中间结果⼊栈break;case'*':value = left * right;opndStack.push(value); // 中间结果⼊栈break;case'/':if (right == 0){cerr << "Divide by 0!" << endl;}else{value = left / right;opndStack.push(value);}break;default:break;}}else{optrStack.pop();if (optr == '(')i++;}}}result = opndStack.top();}int main(){MakePriority(); // 构造运算符优先级表cout << "请输⼊中缀表达式:";cin >> infix;cout << "直接利⽤中缀表达式求值为:";CalculateByInfix();cout << result << endl;cout << "转化为后缀表达式:";InfixToPostfix();for (int i = 0;i < strlen(postfix);i++){cout << postfix[i];}cout << endl;cout << "利⽤后缀表达式求值为:";CalculateByPostfix();cout << result << endl;return0;} 为了⽅便起见,本⽂只是简单的设计了⼀个针对⼀位整数的四则运算进⾏求值的算法,对于处理多位整数的四则运算,需要对本⽂接受输⼊的数据类型进⾏“升阶”,把字符数组换成字符串数组,将⼀个整数的多位数字存⼊⼀个字符串进⾏处理。

四则运算表达式求值(栈+二叉树-c++版)

四则运算表达式求值(栈+二叉树-c++版)

HUNAN UNIVERSITY 课程实习报告题目:四则运算表达式求值学生:周华毅学生学号:201308010411专业班级:计科1304 指导老师:吴帆完成日期:2015/5/1一、需求分析a)四则运算表达式求值,将四则运算表达式用中缀表达式表示,然后转换为后缀表达式,并计算结果。

b)本程序要求利用二叉树后序遍历来实现表达式的转换,同时可以使用实验2的结果来求解后缀表达式的值。

c)在字符界面上输入一个中缀表达式,回车表示结束。

如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。

d)测试数据输入:21+23*〔12-6〕输出:21 23 12 6 -*+二、概要设计抽象数据类型为实现上述程序的功能,应以字符串存储用户的输入,以及计算出的结果。

算法的基本思想根据题目要求,利用二叉树后序遍历来实现表达式的转换。

该算法的基本模块包括二叉树的建立以及如何把输入的中缀表达式利用二叉树后序遍历转化为后缀表达式。

1、首先要将输入的中缀表达式〔数字字符〕存入到二叉树中,由于存在两位或者两位以上的数,甚至还有小数,所以考虑用字符型指针存储数字字符和操作符。

2、为了便于将中缀表达式存入二叉树中,在录入中缀表达式后,要进行相应的处理,比方去掉空格符,添加结束标志,如‘=’、‘#’等。

3、中缀表达式存入到二叉树的过程中,要注意处理的顺序,如‘+’、‘-’号的优先级比‘*’、‘/’号的低,当遇到‘*’、‘/’号时,要判断树以上的节点中是否有‘+’、‘-’号,有的话要与其交换位置。

遇到‘〔’时要反复创建二叉树的结点,构建子二叉树,考虑到括号内要处理的步骤可能会较多,可以考虑用递归。

遇到‘〕’时则直接结束此子二叉树的建立。

此外二叉树中叶子结点存储操作数,非叶子结点存储操作码。

4、对创建好的二叉树进行后序遍历,即可得到相应的后缀表达式,实现方法可以用递归的方式,由于后面还要计算表达式的值,故便利的过程中要将结点中得到的数据存入新的字符数组中。

c语言求解带括号的四则运算表达式

c语言求解带括号的四则运算表达式

c语言求解带括号的四则运算表达式如何用C语言求解带括号的四则运算表达式在C语言中,我们可以使用栈来求解带括号的四则运算表达式。

栈是一种先入后出(Last-In-First-Out)的数据结构,对于表达式中的每一个运算符,我们都可以使用栈来保存其优先级。

下面是一步一步的解决方法。

第一步:定义运算符优先级在处理表达式时,我们需要知道每个运算符的优先级。

在C语言中,可以使用switch语句来定义每个运算符的优先级。

例如:cint getPriority(char op) {switch(op) {case '+':case '-':return 1;case '*':case '/':return 2;case '(':case ')':default:return 0;}}在这个函数中,我们将运算符+和-的优先级定义为1,将运算符*和/的优先级定义为2,而括号的优先级定义为0。

第二步:将表达式转换为后缀表达式后缀表达式是指将运算符放在操作数之后的表达式形式。

为了求解带括号的四则运算表达式,我们首先需要将其转换为后缀表达式。

具体的转换规则如下:1. 从左到右扫描表达式,如果遇到操作数,则直接将其输出。

2. 如果遇到运算符,则将其与栈顶的运算符比较优先级。

如果栈顶的运算符优先级大于等于当前的运算符,则将栈顶的运算符弹出并输出,直到栈顶的运算符优先级小于当前的运算符或者栈为空。

然后将当前的运算符压入栈中。

3. 如果遇到左括号,则直接将其压入栈中。

4. 如果遇到右括号,则将栈顶的运算符弹出并输出,直到遇到左括号为止。

左括号不输出。

例如,对于表达式"3 + 4 * ( 2 - 1 )",其转换为后缀表达式为"3 4 2 1 - * +"。

第三步:求解后缀表达式在将表达式转换为后缀表达式之后,我们可以使用栈来求解后缀表达式。

带有括号的四则运算

带有括号的四则运算

带有括号的四则运算(带有括号的四则运算)在数学中,四则运算是一种基本的数学运算方法,包括加法、减法、乘法和除法。

而带有括号的四则运算则是在表达式中使用括号来改变运算的优先级和顺序。

本文将对带有括号的四则运算进行详细讨论。

1. 括号的作用括号在数学中起到改变运算顺序的作用。

当一个表达式中存在括号时,需要首先计算括号内的运算,然后按照运算符的优先级进行计算。

括号可以改变运算的优先级,使得先计算括号内的运算,然后再进行其他运算。

例如,(3+4)*5的结果是35,而不是7*5=35。

2. 括号的优先级在带有括号的四则运算中,乘法和除法的优先级高于加法和减法。

因此,在计算带有括号的表达式时,需要先计算括号内的乘法和除法运算,然后再进行加法和减法运算。

3. 括号的嵌套括号可以进行嵌套,即一个括号内再包含另一个括号。

在计算带有嵌套括号的表达式时,需要先计算最内层的括号内的运算,然后逐层向外计算。

4. 括号的应用举例以下是一些带有括号的四则运算的示例:例子一:(5+3)*2首先计算括号内的加法运算,得到8,然后再乘以2,最终结果为16。

例子二:(2+3)*4-(10-2)首先计算括号内的加法运算,得到5,然后再乘以4,得到20。

接着计算括号内的减法运算,得到8。

最后将20减去8,最终结果为12。

例子三:(3+2)/(1+1)首先计算括号内的加法运算,得到5,然后计算括号内的加法运算,得到2。

最终结果为2.5。

通过以上示例可以看出,括号的运用可以使得运算的结果更加准确和清晰,避免了因为运算优先级引起的错误。

5. 注意事项在进行带有括号的四则运算时,需要注意以下几点:- 括号要成对出现,即每个左括号都需要有一个相应的右括号。

- 括号的数量要匹配,即左括号的数量要等于右括号的数量。

- 注意括号的嵌套次数,以免造成运算混乱。

- 在进行复杂的带有括号的四则运算时,可以使用计算器或编程语言来辅助计算,避免出现错误。

总结:带有括号的四则运算是数学中常见的运算方法之一,通过改变运算优先级和顺序,可以使得运算结果更加准确和清晰。

堆栈 实现四则运算,直接能跑

堆栈 实现四则运算,直接能跑

#include<stdio.h>#include<string.h>#define MaxSize 100typedef struct{int data[MaxSize];int top;}DataStack;int InitStack(DataStack *S){S->top = -1;memset(S->data, '\0', sizeof(int) * MaxSize);return 1;}int StackEmpty(DataStack S){return S.top == -1;}int Push(DataStack *S, char e){if (S->top >= MaxSize - 1) {printf("Stack is full!\n");return 0;} else {S->data[++S->top] = e;return 1;}}int Pop(DataStack *S){if (S->top >= 0) {return S->data[S->top--];} else {printf("Stack is empty!\n");return 0;}}int trans(DataStack *S,char *exp,char postexp[]) {int i=0;while(*exp!='\0'){switch(*exp){case '(':Push(S,*exp);exp++;break;case ')': while(S->data[S->top]!='('){postexp[i++]=Pop(S);}Pop(S);exp++;break;case '+':case '-':Push(S,*exp);while(S->top!=-1&&S->data[S->top]!='('){postexp[i++]=Pop(S);}exp++;break;case '*':case '/':Push(S,*exp);while(S->data[S->top]=='*'||S->data[S->top]=='/'){postexp[i++]=Pop(S);}exp++;break;case ' ': break;default : while(*exp>='0' && *exp<='9'){postexp[i++]=*exp;exp++;postexp[i++]='#';}}while(S->top!=-1){postexp[i++]=Pop(S);}postexp[i]='\0';}float compvalue(DataStack *S,char *postexp) {float a,b,c,d;float value;while(*postexp!='\0'){switch(*postexp){case '+':a=Pop(S);b=Pop(S);c=a+b;Push(S,c);break;case '-':a=Pop(S);b=Pop(S);c=b-a;Push(S,c);break;case '*':a=Pop(S);b=Pop(S);c=a*b;Push(S,c);break;case '/':a=Pop(S);b=Pop(S);if(a!=0){Push(S,c);}else{printf("零不能作除数\n");return ;}break;default :d=0;while(*postexp>='0'&&*postexp<='9'){d=10*d+*postexp-'0';postexp++;}Push(S,d);break;}postexp++;}return Pop(S);}int main(){DataStack S;InitStack(&S);char exp[20];scanf("%s",exp);char postexp[MaxSize];float value;trans(&S,exp,postexp);printf("后缀表达式的值:%s\n",postexp);value=compvalue(&S,postexp);printf("表达式的值:%.2f\n",value);}。

四则运算表达式求值

四则运算表达式求值

HUNAN UNIVERSITY背景在工资管理软件中,不可避免的要用到公式的定义及求值等问题。

对于数学表达式的计算,虽然可以直接对表达式进行扫描并按照优先级逐步计算,但也可以将中缀表达式转换为逆波兰表达式,这样更容易处理。

问题描述四则运算表达式求值,将四则运算表达式用中缀表达式,然后转换为后缀表达式,并计算结果。

一.需求分析(1)本程序利用二叉树后序遍历来实现表达式的转换,同时可以使用栈来求解后缀表达式的值。

(2)输入输出的格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。

输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式和计算结果,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。

(3)测试用例:输入:21+23*(12-6)+9输出:21 23 12 6 -*+ 9+result is 168二.概要设计(1)抽象数据类型:由于四则运算表达式中运算符可能有多个后继,而运算的对象无后继,可以采用二叉树来实现把中缀表达式转换为后缀表达式。

数据对象:四则运算符及整数数据关系:运算符有多个后继,二运算对象的值无后继基本操作:后序遍历,二叉树的构建和摧毁,插入,删除经过二叉树的后序遍历后的表达式惊醒运算是满足后进先出的原则,采用栈来实现四则运算表达式的求值。

数据对象:运算符(字符)及整数数据关系:后进先出基本操作:入栈,出栈,栈的构建和删除(2)算法基本思想:用二叉树来存储四则表达式,再通过后序遍历把中缀表达式转换为后缀表达式,最后通过栈来计算表达式的值,最后输出后序表达式和表达式的值。

(3)程序的流程:该程序有三个模块组成:1.输入模块:输入一个中缀表达式2.处理模块:把中缀表达式转换为后缀表达式3.计算模块:计算表达式的值4.输出模块:输出后缀表达式及表达式的值三.详细设计(1)物理数据类型:采用指针来实现二叉树,其中分支节点存储运算符,用叶子节点存储操作数,可以减少二叉树的结构性开销。

栈实现表达式的简单求值

栈实现表达式的简单求值

利用栈编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。

要求输出表达式的值此题目可选做。

注意:计算的结果数值不可以大于79.#include<stdio.h>#include<malloc.h>#define OK 1#define ERROR 0#define STACK_INIT_SIZE 100 // 存储空间初始分配量typedef struct{char *base;char *top;int stacksize;}Stack;int InitStack(Stack &S){S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char)); if(!S.base) return ERROR;S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}int Pop(Stack &S,char &e){if(S.top==S.base) return ERROR;e=*--S.top;return OK;}int GetTop(Stack S,char &e){if(S.top==S.base) return ERROR;e=*--S.top;return OK;}int Push(Stack &S,char ch){if(S.top-S.base>=S.stacksize){S.base=(char*)realloc(S.base,(S.stacksize+10)*sizeof(char)); if(!S.base) return ERROR;S.top=S.base+S.stacksize;S.stacksize+=10;}*S.top++=ch;return OK;}char Compare(char &e,char ch){switch(e){case '+':if(ch=='+'||ch=='-'||ch==')') return '>';else return '<';break;case '-':if(ch=='+'||ch=='-'||ch==')') return '>';else return '<';break;case '*':if(ch=='(')return '<';else return '>';break;case '/':if(ch=='(')return '<';else return '>';break;case '(':if(ch==')')return '=';else return '<';break;case ')':return '>';break;}}int Cal(char a,char theta,char b) {int s;a-=48;b-=48;switch(theta){case '+':s=a+b;break;case '-':s=a-b;break;case '*':s=a*b;break;case '/':s=a/b;break;}return s;}int StackEmpty(Stack S){if(S.top==S.base) return OK; return ERROR;}int Operator(){Stack CS;Stack NS;char ch,e;char a,b,theta;InitStack(CS);InitStack(NS);//Push(CS,'=');ch=getchar();while(ch!='='){if(ch>='0'&&ch<='9'){Push(NS,ch);ch=getchar();if(ch>='0'&&ch<='9'){Pop(NS,a);Push(NS,((a-48)*10+(ch-48))+48); ch=getchar();}}else{if(StackEmpty(CS)){Push(CS,ch);ch=getchar(); continue;}GetTop(CS,e);switch(Compare(e,ch)) {case '<':Push(CS,ch); ch=getchar();break;case '=':Pop(CS,e);ch=getchar();break;case '>':Pop(CS,theta);Pop(NS,a);Pop(NS,b);Push(NS,Cal(b,theta,a)+48); break;}}}while(Pop(CS,theta)){Pop(NS,a);Pop(NS,b);Push(NS,(Cal(b,theta,a)+48)); }GetTop(NS,ch);return (ch-48);}int main(){printf("%d\n",Operator()); return 0;}输入格式第一行:一个算术表达式输出格式第一行:算术表达式的值输入样例3*(9-7)=(0-12)*((5-3)*3)/(2+2)=输出样例6-18。

C++实现四则运算器(带括号)

C++实现四则运算器(带括号)

C++实现四则运算器(带括号)基本分析可以看另⼀篇⽂章栈的实现//stack.h#ifndef STACK_H#define STACK_H#include<iostream>class stack_int{private:int* bottom; //栈底int* top; //栈顶unsigned int capacity;//栈容量unsigned int size; //栈⼤⼩public:stack_int() :bottom(new int[11]), top(bottom), capacity(10), size(0) {};stack_int(unsigned int capacity) :bottom(new int[capacity+1]),top(bottom), capacity(capacity),size(0){};int operator[](unsigned int i) const{return *(bottom + i);}bool isEmpty()const { return bottom == top; }bool isFull()const { return size == capacity-1; }unsigned int getsize()const { return size; }unsigned int getcapacity()const { return capacity; }int gettop()const{if (!isEmpty())return *(top - 1);elsereturn -1;}void settop(int i){if (!isEmpty()){*(top - 1) = i;}}void push(int i){if ((top - bottom)<capacity){*top = i;top++;size++;}else{std::cout << "stack full!" << std::endl;stack_expansion();push(i);}}int pop(int &val){//返回值为1则栈未空,返回值为0则栈已空⽆法出栈if (top > bottom){top--;size--;val = *top;return 1;}else{std::cout << "stack empty!" << std::endl;return NULL;}}private:void stack_expansion(){//栈扩容std::cout << "正在扩容中..." << std::endl;int newcapacity = 2 * capacity + 1;int* newbottom = new int[newcapacity + 1];int* newtop = newbottom;for (int i = 0; i < size; ++i){*newtop = *bottom;newtop++;bottom++;}bottom = newbottom;top = newtop;capacity = newcapacity;}};#endif主程序//Main.c#include"stack.h"#include<iostream>using namespace std;bool is_digit(char i){//是数字if (i == '1' || i == '2' || i == '3' || i == '4' || i == '5' || i == '6' || i == '7' || i == '8' || i == '9' || i == '0') return true;else return false;}bool is_operator(char i){//是运算符if (i == '+' || i == '-' || i == '*' || i == '/' || i == '(' || i == ')'||i=='=')return true;else return false;}bool get_priority(char pre,char cur){//获取两个符号间的优先级,pre为靠前的字符,cur为靠后的字符if ((pre == '+' || pre == '-') && (cur == '*' || cur == '/'))return false;else if (pre == '(' || cur == '(')return false;elsereturn true;}int do_operation(int lnum, char ope, int rnum){if (ope == '+')return lnum + rnum;if (ope == '-')return lnum - rnum;if (ope == '*')return lnum * rnum;if (ope == '/')return lnum / rnum;}/*1+2*3=1*(2+1*(3+5)+4*3)=先乘除,后加减,有括号先算括号内的1+5*4-345+36/6*4+145*4*5-52=*/void do_arithmetic(){stack_int s;stack_int num_stack;//数据栈stack_int ope_stack;//符号栈char current_char;current_char = getchar();bool overflag = false;//结束标志bool errorflag = false;//出错标志while (overflag != true){//未遇到=号时不断进⾏四则运算if (is_digit(current_char)){//遇到数字符号则将完整的数解析出来并保存于栈中int num = 0;num = current_char - '0';//符号转数字current_char = getchar();//获取下⼀个字符while (is_digit(current_char)){num = num * 10 + (current_char - '0');current_char = getchar();}num_stack.push(num);//cout <<"the number is " <<num << endl;}if (current_char == ' '||current_char=='\n'){//空格或换⾏则继续current_char = getchar();continue;}if (is_operator(current_char)){//遇到运算符则将运算符保存于运算符栈中int ope = '?';//如果当前符号栈⾮空,则不断根据优先级决定是否进⾏⼀次运算while ((!ope_stack.isEmpty()) && (get_priority((char)ope_stack.gettop(), current_char))) {//如果前⼀个运算符优先级更⾼ope_stack.pop(ope);//cout << "找到了前⼀个运算符为: " << (char)ope << endl;int lnum, rnum;//符号栈⾮空时,数据栈应该⾄少有两个数,否则出错if (num_stack.isEmpty()){cout << "error: 数据栈缺失两个元素,解析失败!" << endl;errorflag = true;overflag = true;break;}num_stack.pop(rnum);if (num_stack.isEmpty()){cout << "error: 数据栈缺失⼀个元素,解析失败!" << endl;errorflag = true;overflag = true;break;}num_stack.pop(lnum);lnum = do_operation(lnum, (char)ope, rnum);//进⾏运算num_stack.push(lnum);}if (current_char == '='){//如果解析到=号了,解析完成if (!ope_stack.isEmpty()){errorflag = true;cout << "error: 缺失)" << endl;}overflag = true;break;}ope_stack.push(current_char);if (current_char == ')'){//右括号则出栈两次,将右括号和匹配的左括号出栈ope_stack.pop(ope);if (ope_stack.isEmpty()){cout << "error: 没有与)相匹配的(" << endl;errorflag = true;overflag = true;break;}ope_stack.pop(ope);}current_char = getchar();}}//for (int i = 0; i < num_stack.getsize(); ++i)// cout << num_stack[i] << "\t";//cout << endl;//for (int i = 0; i < ope_stack.getsize(); ++i)// cout << (char)ope_stack[i] << "\t";if (!errorflag)cout << num_stack.gettop() << endl;}int main(){cout << " ______________" << endl;cout << "|整数四则运算器|" << endl;cout << " --------------" << endl;cout << "功能介绍:进⾏整数表达式的四则运算" << endl;cout << "可以使⽤的运算符:+ - * /" << endl;cout << "使⽤⽅式:输⼊以=结尾的算数运算表达式,回车后即可得到运算结果" << endl; cout << endl;//2432+5423-534*42=while (true){cout << "____________________" << endl;cout << "--------------------" << endl;cout << "> ";do_arithmetic();}return 0;}程序⼤部分与不带括号版本很相似,主要更改了两个⽅⾯:1.对于左括号,令左括号左边运算符优先级低于左括号,右边运算符优先级⾼于左括号(即,只要含有左括号的⽐较结果均为⽆法进⾏运算,函数get_priority返回值永远为false)。

括号匹配算法求解(用栈实现)

括号匹配算法求解(用栈实现)

括号匹配算法求解(⽤栈实现)1.括号匹配算法//括号匹配算法public void pipei()throws Exception{char temp,ch;int match; //记录匹配结果BufferedReader br = new BufferedReader(new InputStreamReader(System.in));ch=(char) br.read(); //输⼊⼀个字符while(ch!='0'){if(getTop()==-1){push(ch);}else{temp=pop(); //取出栈顶元素match=0; //判断是否匹配(默认不匹配)if(temp=='('&&ch==')')match=1;if(temp=='['&&ch==']')match=1;if(temp=='{'&&ch=='}')match=1;if(temp=='<'&&ch=='>')match=1;if(match==0){ //如果不匹配push(temp); //将原栈顶元素重新⼊栈push(ch); //将输⼊的括号字符⼊栈}}ch=(char) br.read(); //输⼊下⼀个字符}if(isEmpty()){System.out.println("输⼊的括号完全匹配!");}else{System.out.println("输⼊的括号不匹配,请检查!");}}2.括号匹配求解⽰例package .datastruct;import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Scanner;public class KuoHaoPiPei {static class Stack{char[] data; //存放数据int MaxSize; //最⼤容量int top; //栈顶指针//构造⽅法public Stack(int MaxSize){this.MaxSize=MaxSize;data = new char[MaxSize];top = -1;}public int getMaxSize() {return MaxSize;}public int getTop() {return top;}public boolean isEmpty(){return top==-1;}public boolean isFull(){return top+1==MaxSize;}//⼊栈public boolean push(char data){if(isFull()){System.out.println("栈已满!");return false;}this.data[++top]=data;return true;}//出栈public char pop() throws Exception{if(isEmpty()){throw new Exception("栈已空!");}return this.data[top--];}//获得栈顶元素public char peek(){return this.data[getTop()];}//括号匹配算法public void pipei()throws Exception{char temp,ch;int match; //记录匹配结果BufferedReader br = new BufferedReader(new InputStreamReader(System.in));ch=(char) br.read(); //输⼊⼀个字符while(ch!='0'){if(getTop()==-1){push(ch);}else{temp=pop(); //取出栈顶元素match=0; //判断是否匹配(默认不匹配)if(temp=='('&&ch==')')match=1;if(temp=='['&&ch==']')match=1;if(temp=='{'&&ch=='}')match=1;if(temp=='<'&&ch=='>')match=1;if(match==0){ //如果不匹配push(temp); //将原栈顶元素重新⼊栈push(ch); //将输⼊的括号字符⼊栈}}ch=(char) br.read(); //输⼊下⼀个字符}if(isEmpty()){System.out.println("输⼊的括号完全匹配!");}else{System.out.println("输⼊的括号不匹配,请检查!");}}}public static void main(String[] args) throws Exception {String go;Scanner input = new Scanner(System.in);Stack stack = new Stack(20);System.out.println("括号匹配问题!");do{System.out.println("请输⼊⼀组括号的组合,以0表⽰结束。

利用堆栈实现四则运算

利用堆栈实现四则运算

利用堆栈实现四则运算#include#include#include "stdlib.h"#includeusing namespace std;#define MAXSIZE 1024typedef char DataType;DataType Exp[8][8]={' ', '+', '-', '*', '/', '(', ')', '#', '+', '>', '>', '<', '<', '<', '>', '>','-', '>', '>', '<', '<', '<', '>', '>','*', '>', '>', '>', '>', '<', '>', '>','/', '>', '>', '>', '>', '<', '>', '>','(', '<', '<', '<', '<', '<', '=', ' ',')', '>', '>', '>', '>', ' ', '>', '>','#', '<', '<', '<', '<', '<', ' ', '='};//操作符栈typedef struct{DataType data[MAXSIZE]; //栈的数据元素int top; //top指向栈顶}SqStack;typedef struct{double data[MAXSIZE];int top;}NumStack;//初始化操作符栈SqStack StackInit(){SqStack S;S.top=-1;return S;}NumStack NumStackInit(){NumStack S;S.top=-1;return S;}/*//检查顺序站是否为空,栈空返回1,不空返回0 int Empty(SeqStack S){if(S.top==-1) return 1;else return 0;}*///把栈置空SqStack StackClear(SqStack S){S.top=-1;return S;}//把元素放入栈中,使其成为栈顶元素void Push(SqStack &S,DataType x){S.top++;S.data[S.top]=x;}//弹出栈顶元素DataType Pop(SqStack &S){S.top--; //栈顶减一return (S.data[S.top+1]); //返回栈顶元素}//取栈顶元素DataType GetT op(SqStack S){return(S.data[S.top]);}//判断优先关系DataType Precede(DataType b1,DataType b2) {int i,j;for(i=0;i<=7;i++){if(b1==Exp[i][0])break;}for(j=0;j<8;j++){if(b2==Exp[0][j])break;}return Exp[i][j];}//判断是否为运算符,是返回turebool In(DataType ch){int i;for(i=0;i<=7;i++){if(ch==Exp[i][0])return true;}if(i==8) return false;else return true;}//运算double Operate(DataType ch,double a,double b) {switch(ch){case '+':return a+b;break; case '-':return b-a;break;case '*':return a*b;break;case '/':return b/a;break; default:break;}}//获得数字double OpndNum(SqStack &S) {string s="";double a=1;while(GetT op(S)!='#'||a>0){if(GetT op(S)!='#'){s=Pop(S)+s;a--;}if(GetT op(S)=='#'&&a==1) Pop(S);}istringstream iss(s);iss>>a;return a;}//运算操作double EvaluateExpression(){cout<<"*******************************************\n"; cout<<"\t\t四则运算求值\n";cout<<"*******************************************"; SqStack OPTD; //OPTD运算符栈SqStack OPND; //OPND操作数栈NumStack Num;OPTD=StackInit();OPND=StackInit();Num=NumStackInit();Push(OPTD,'#');Push(OPND,'#'); //运算符栈底为#,退出时遇到#结束运算DataType t;int sLengh=0,i=0;double a,b;cout<<"\n输入表达式:";string exp;cin>>exp;exp+='#';//获取字符串长度while(exp[sLengh]!='#'){sLengh++;}while(!(exp[i]=='#'&&GetTop(OPTD)=='#')){if(!In(exp[i])||(GetT op(OPTD)=='('&&exp[i]=='-')||(GetT op(OPTD)=='#'&&exp[i]=='-'))//当当前字符不在运算符集合里面时{Push(OPND,exp[i]);i++;}else//为运算符时{switch(Precede(GetTop(OPTD),exp[i])){case '<':Push(OPTD,exp[i]);i++;break;case '=':Pop(OPTD);i++;break;case '>':t=Pop(OPTD);if(Num.top==-1){a=OpndNum(OPND);}else a=Num.data[Num.top--]; b=OpndNum(OPND);a=Operate(t,a,b);Num.data[++Num.top]=a; break;default:break;}Push(OPND,'#');}}StackClear(OPND); StackClear(OPTD);return a;}int main(){double re;re=EvaluateExpression(); cout<<"\n运算结果为:"; cout<<re;cout<<"\n\n";return 0;}</re;。

四则运算c++实现

四则运算c++实现

四则运算c++实现一、需求分析1. 利用二叉树后序遍历来实现表达式的转换,同时可以使用实验3的结果来求解后缀表达式的值。

2. 输入输出格式:输入:在字符界面上输入一个中缀表达式,回车表示结束。

输出:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后缀表达式中两相邻操作数之间利用空格隔开;如果不正确,在字符界面上输出表达式错误提示。

二、概要设计抽象数据类型为实现上述程序的功能,前序遍历输入,以后序遍历输出。

算法的基本思想用一个字符串储存输入的二项式,一次读取各个字符。

如果遇见数据,累乘后存入后序遍历的数组当中(将字符型转换为整数类型);如果遇见前括号,存入运算符栈中;如果遇见后括号,将前括号及前括号之后的运算符全部弹出;如果遇见加减号,在运算符栈为空或下一个为括号运算符时,运算符入栈,否则,将栈顶元素存入后序遍历的数组中,再运算符入栈;如果遇见乘除号,在运算符栈为空或下一个为括号运算符时及栈内第一个元素为乘号或除号时,运算符入栈,否则,将栈顶元素存入后序遍历的数组中,再运算符入栈。

程序的流程程序由三个模块组成:(1)输入模块:输入正确的四则运算表达式。

(2)计算模块:利用栈实现四则运算。

(3)输出模块:屏幕上显示后序遍历的结果。

三、详细设计物理数据类型1、用数组存储输入的表达式和输出的表达式。

2、用栈存储操作算法的具体步骤求逆序遍历的算法算法的时空分析后序遍历的时间代价为Θ(n)空间代价为一个数组.输入和输出的格式输入:请输入中序表达式:xxx#(#结束符)输出:输出的后缀是:五、测试结果输入:5*(3+2)!输出:5#3#2#+*The result is:25六、用户使用说明(可选)1、“! ” 结束符2、输入的包括符号请不要超过十位七、实验心得(可选)1:这次试验的优点是在不断地调试和运行之后终于实现了这个代码,完成了c++创建栈的全部过程,让我的这个小组对栈的了解有人更加深入的认识,完成了栈的所有的基本操作,但是缺点在于这次试验的代码并不是完全符合条件,没有用树的遍历实现。

括号与四则运算计算

括号与四则运算计算

括号与四则运算计算在数学中,括号与四则运算是非常重要的概念。

括号在四则运算中的使用,可以改变计算的顺序,从而使结果更加准确。

本文将详细介绍括号与四则运算的计算规则和应用。

一、加法与减法在四则运算中,加法和减法是最基本的运算符号。

当表达式中只有加法和减法时,计算顺序从左至右进行。

例如,计算表达式:2 + 3 - 4 + 5按照从左至右的顺序进行计算,先进行2 + 3的运算,得到5,再进行5 - 4的运算,得到1,最后进行1 + 5的运算,得到6。

二、乘法与除法乘法和除法在四则运算中的优先级高于加法和减法。

当表达式中有乘法和除法时,应先进行乘法和除法的运算,再进行加法和减法的运算。

例如,计算表达式:2 + 3 × 4 - 5 ÷ 2首先进行乘法和除法的运算,3 × 4得到12,5 ÷ 2得到2.5。

然后再进行加法和减法的运算,2 + 12得到14,14 - 2.5得到11.5。

三、括号的运算规则括号在四则运算中具有最高的优先级,可以改变运算的顺序。

括号内的运算先于其他运算进行。

例如,计算表达式:(2 + 3) × 4 - (5 ÷ 2)首先计算括号内的运算,2 + 3得到5。

然后再进行乘法和除法的运算,5 × 4得到20,5 ÷ 2得到2.5。

最后进行减法的运算,20 - 2.5得到17.5。

四、多个括号的运算规则当表达式中存在多个括号时,应先计算最内层的括号,再依次向外计算。

例如,计算表达式:(2 + (3 - 1)) × (4 - 2)首先计算括号内的运算,3 - 1得到2,2 + 2得到4。

然后进行外层括号内的运算,4 × 4得到16。

综上所述,括号与四则运算是需要注意的数学概念。

在进行计算时,我们应遵循先乘除后加减的原则,并根据需要使用括号来改变运算的顺序,从而得到准确的计算结果。

理解和掌握括号与四则运算的规则,将有助于我们在解决数学问题时提高计算的准确性和效率。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

带括号的四则运算表达式的求值(栈实现)
利用栈这种数据结构来实现一个加减乘除以及带括弧的混合数学表达式的计算,对于数学表达式的计算,可以设置一个运算符栈和一个数字栈,分别来保存运算符、数字或者中间计算得到的结果。

将整个表达式看做一个字符串,从开头依次判断每个字符是运算符还是数字,若是运算符,则根据运算符优先级来确定是将其压栈还是弹栈进行计算;若是数字,则先将其转化并计入一个临时double型变量中,看下一个字符是否为运算符栈,若是,则将临时变量压进数字栈,否则读取下一个数字字符并进行相关处理后累加到临时变量中,直到下一个字符为运算符,将临时变量压进数字栈。

最后,当字符为"="时,结束计算,得到计算结果。

本算法需要先设置一个运算符优先级表,下表可供参考:
+-*/()=
+>><<<>>
->><<<>>
*>>>><>>
/>>>><>>
(<<<<<=
)>>>>?>>
=<<<<<?=
参考代码如下:
注:本代码输入表达式时末尾不需要“=”,程序中会自动添加
#include
#include
#include
#include
#include
using namespace std;
char Precede(char a, char b) { {
point = 10;
else
num = s[i] - 48;
j = i + 1;
while(!IsOper(s[j])) { {
point = 10;
j++;
continue;
}
if(!point)? 5 - 7 /
2 + 3. - .1
1 +
2 / ( 2 - / ) - 3
2 * ( (
3 + 2 ) - 3
*/
本代码生成的程序,在输入表达式时,数字与运算符之间可以有若干空格或者没有;对于小数,可以没有整数部分(即小数点之前没有数字),也可以没有小数部分(即小数点之后没有数字);表达式可以为无效表达式(如括号不匹配或者出现除数为0的情况等);如以上的样例输入。

对于以上样例输入,其对应输出结果为:
The divisor cannot be zero!
The parentheses do not match!
相关文档:










更多相关文档请访问:。

相关文档
最新文档