利用栈实现c语言计算器
C语言实现计算器功能
C语言实现计算器功能C语言计算器实现是一种基本的编程练习,可以结合简单的数学表达式解析和计算功能来实现一个基本的计算器。
以下是一个简单的示例,它可以接受用户输入的数学表达式并返回计算结果。
首先,我们需要包含标准输入/输出库(stdio.h)和字符串处理库(string.h)。
我们还需要定义一些函数来处理数学表达式的解析和计算。
```c#include <stdio.h>#include <string.h>//返回运算符的优先级int precedence(char op)if (op == '+' , op == '-')return 1;if (op == '*' , op == '/')return 2;return 0;//执行四则运算int calculate(int a, int b, char op)switch (op)case '+':return a + b;case '-':return a - b;case '*':return a * b;case '/':return a / b;}return 0;//解析数学表达式并计算结果int evaluate(char *expression)int i;//创建两个空栈,用于操作数和运算符int values[100];int top_values = -1;char ops[100];int top_ops = -1;//遍历表达式的每个字符for (i = 0; i < strlen(expression); i++)//如果字符是一个数字,将其解析为整数,并将其推到操作数栈中if (expression[i] >= '0' && expression[i] <= '9')int value = 0;while (i < strlen(expression) && expression[i] >= '0' && expression[i] <= '9')value = value * 10 + (expression[i] - '0');i++;}values[++top_values] = value;}//如果字符是一个左括号,将其推到运算符栈中else if (expression[i] == '(')ops[++top_ops] = expression[i];}//如果字符是一个右括号,执行所有高优先级的运算else if (expression[i] == ')')while (top_ops > -1 && ops[top_ops] != '(')int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}top_ops--;}//如果字符是一个运算符,执行所有高优先级的运算elsewhile (top_ops > -1 && precedence(ops[top_ops]) >= precedence(expression[i]))int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}ops[++top_ops] = expression[i];}}//执行剩余的运算while (top_ops > -1)int b = values[top_values--];int a = values[top_values--];char op = ops[top_ops--];values[++top_values] = calculate(a, b, op);}//返回最终结果return values[top_values];int mainchar expression[100];printf("请输入数学表达式:");scanf("%s", expression);int result = evaluate(expression);printf("结果:%d\n", result);return 0;```上面的代码使用了栈来解析和计算数学表达式。
栈实现计算器(简单四则运算)
栈实现计算器(简单四则运算)主要是通过定义⼀个数栈和⼀个符号栈,并根据给出的计算式进⾏拆分,循环判断是数字还是符号,考虑数字的连续性和符号计算的优先级,具体实现如下: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的表达式后⾯在扫描⼀位,如果是数继续扫描,如果是符合则停⽌。
C语言实现简易计算器(可作加减乘除)
C语⾔实现简易计算器(可作加减乘除)C语⾔实现简易计算器(加减乘除)计算器作为课设项⽬,已完成答辩,先将代码和思路(注释中)上传⼀篇博客已增添、修改、整理⾄⽆错且可正常运⾏虽使⽤了栈,但初学者可在初步了解栈和结构语法后理解代码#include <stdlib.h>#include <stdio.h>#include <string.h>#define IsDouble 0#define IsChar 1//_______________________________________________________________________________________________________________________________________________________ //1.⽀持浮点数和字符的栈typedef struct {char * buffer;int typesize;int top;int max;} stack;stack * CreateStack(int max, int typesize);//创建⼀个栈void DestroyStack(stack *);//释放栈的空间void ClearStack(stack *);//清空栈int Push(stack *, void *);//⼊栈int Pop(stack *, void *);//出栈int GetSize(stack *s);//得到栈的⼤⼩int GetTop(stack *, void *);//找到栈顶int IsEmpty(stack *);//判断是否为空栈,空则下溢int IsFull(stack *);//判断栈是否已满,满则溢出stack * CreateStack(int max, int typesize){stack * s = (stack*)malloc(sizeof(stack));//为栈s malloc内存if (!s) return 0;//为结构中buffer元素malloc内存s->buffer = (char *)malloc(sizeof(char) * max * typesize);if (!s->buffer) return 0;//初始化结构中的栈顶,最⼤值,类型⼤⼩s->top = -1;s->max = max;s->typesize = typesize;return s;}void DestroyStack(stack* s){free(s->buffer);//先释放buffer的空间free(s);//在释放s的空间}void ClearStack(stack * s){s->top = -1;//清空栈(栈头位置归零)}int Push(stack * s, void * data){if (IsFull(s)) return 0;//如果栈已满则return 0,防⽌溢出//栈未满则将栈头移动打动下⼀位置,并将data中的元素拷⼊栈中buffer的第top位置s->top++;memcpy(s->buffer + s->top*s->typesize, data, s->typesize);//⼊栈成功return 1return 1;}int Pop(stack * s, void * data){if (IsEmpty(s)) return 0;//出栈判断栈是否为空,若为空则return 0//栈未空则将buffer中top位置的字符拷⼊data记录,并让栈头向前移动⼀个位置memcpy(data, s->buffer + s->top*s->typesize, s->typesize);s->top--;//成功则return 1return 1;}int GetSize(stack *s){return s -> top+1;//栈头位置+1得到⼤⼩}int GetTop(stack *s, void * data){if (IsEmpty(s)) return 0;//如果栈空return 0//栈不为空则将top位置的字符拷回data记录,得到栈头memcpy(data, s->buffer + s->top*s->typesize, s->typesize);//成功则return 1;return 1;}int IsEmpty(stack * s){return s->top == -1;//如果top为-1则栈空}int IsFull(stack * s){return s->top == s->max-1;//如果top为max-1则栈满}//___________________________________________________________________________________________________________________________________________________ //2.定义⼀个cal类型,其中data存数时sign为IsDouble,存字符时,sign为Ischartypedef struct {double data;char sign;} cal;//3.查找对应符号(找到则返回该符号下标)(找不到则说明该部分为数字返回-1)int SearchCode(char ch){char * code = "+-*/()@";//@为终⽌符,算式输⼊结束int index = 0;//while (code[index]){if (code[index] == ch) return index;index++;}return -1;}//4.得到两个符号间的优先级//与SearchCode相对应,char GetPriority(char ch, char next){//创建⼀个perferen表,第i⾏(列)对应SearchCode函数中code中的第i个字符char perferen[7][7] = {">><<<>>",">><<<>>",">>>><>>",">>>><>>","<<<<<=E",">>>>E>>","<<<<<E="};//找到两个形参对应的字符int c = SearchCode(ch);int n = SearchCode(next);//如果找不到对应运算符(字符不是运算符⽽是为数字)return Eif (c==-1 || n==-1) return 'E';//如果找到两个对应运算符则按照优先级表返回两个运算符的优先级return perferen[c][n];}//5.四则运算double add(double a, double b) { return a+b; }double sub(double a, double b) { return a-b; }double mul(double a, double b) { return a*b; }double ddiv(double a, double b) { return a/b; }//整合四种运算double calcu(double a, char ch, double b){double (*calculation[4])(double,double) = {add,sub,mul,ddiv};return calculation[SearchCode(ch)](a,b);}//6.检测字符串int CheckStr(char * buffer){int n;//遍历字符串确保算式中⽆⾮法字符若检测到⾮法字符return 0,若都合法则return 1for (n = 0;buffer[n];n++){if ((SearchCode(buffer[n]) != -1 || buffer[n] == '.' || (buffer[n] >= '0' && buffer[n] <= '9')) && buffer[n] != '@') continue;else return 0;}buffer[n] = '@';//加上终⽌符,表⽰算式结束buffer[n+1] = '\0';return 1;}//7.得到数据转化为double类型存⼊rsint GetDigit(char * buffer, int * n, double * rs){char str[30];int i,j = 0;for (i = 0;SearchCode(buffer[*n]) == -1;i++){str[i] = buffer[*n];//从*n位置开始,将这⼀串数字字符存⼊str(*n)++;}str[i] = '\0';for (i = 0;str[i];i++){if (str[i] == '.') j++;}//如果⼀段⼩数有多个⼩数点或⼩数点在数字⾸尾,return 0if (j>1 || str[i-1] == '.' || str[0] == '.') return 0;//rs接收转化为double的数据*rs = atof(str);//操作成功return 1return 1;}//8.将⽤户输⼊的buffer字符串转化为可供程序运算的calstr数组int resolu(char * buffer, cal * calstr){int i = 0, j = 0;cal c;while (buffer[i]){if (SearchCode(buffer[i]) == -1){//如果得到数据不成功则return 0if (GetDigit(buffer,&i, &c.data) == 0) return 0;//如果成功得到数据则在c.sign标记为浮点数c.sign = IsDouble;//将c存⼊数组calstr中calstr[j++] = c;}else{//若符号为运算符//判断正负号if (buffer[i] == '-' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '-')){ i++;if (GetDigit(buffer,&i, &c.data) == 0) return 0;//在符号的下⼀位开始查找,若找不到数字return 0//否则,给数字取相反数,c.sign标记为浮点数,存⼊calstr中c.data = 0 - c.data;c.sign = IsDouble;calstr[j++] = c;} else//如果是正号,与符号处理⽅式同理if (buffer[i] == '+' && (buffer[i-1] == '('||buffer[i-1] == '+'||buffer[i-1] == '-'||buffer[i-1] == '*'||buffer[i-1] == '/') || (i==0 && buffer[0] == '+')){ i++;if (GetDigit(buffer, &i, &c.data) == 0) return 0;c.sign = IsDouble;calstr[j++] = c;}else{//如果不是正负号,则为运算符,先强制转换为double类型存在c.data⾥,然后c.sign标记为char类型,存⼊calstrc.data = (double)buffer[i++];c.sign = IsChar;calstr[j++] = c;}}}//操作蔡成功则return 1return 1;}//9.计算出结果int result(cal * calstr, double * rs){stack * pst = CreateStack(100,sizeof(char));//运算符栈stack * pnd = CreateStack(100,sizeof(double));//数据栈double num1,num2;int n = 0;char ch = '@';Push(pst, &ch);//在转换得到的calstr中遍历直到终⽌符'@"while(ch != '@' || !(calstr[n].sign == IsChar && (char)calstr[n].data == '@')){//如果calstr的n位上是浮点数,则将这个data压栈进⼊数据栈pnd中if (calstr[n].sign == IsDouble){Push(pnd, &(calstr[n].data));n++;}//反之,如果是运算符,则要检测优先级else{switch( GetPriority(ch, (char)calstr[n].data)){//如果运算符优先级较⼩,则让ch等于优先级⼤的符号并压⼊符号栈pst中case '<':ch = (char)calstr[n].data;Push(pst, &ch);n++;break;//如果结果为等号,让符号出栈暂存到ch中case '=':if (!Pop(pst, &ch)) return 0;n++;break;//如果ch优先级较⾼,则将前两个数字及运算符出栈,分别储存⾄num2,ch,num1中,进⾏运算,得到的结果再次压栈进⼊pnd中 case '>':if (!(Pop(pnd,&num2) && Pop(pst,&ch) && Pop(pnd,&num1))) return 0;num1 = calcu(num1,ch,num2);Push(pnd, &num1);break;//如果符号顺序出错,return 0case 'E':return 0;}}//检测是否可以得到栈顶符号,栈空则return 0if (!GetTop(pst, &ch)) return 0;}//如果栈中得到了最终结果,并且取出pnd中的最终结果到rs,return 1if (GetSize(pnd) == 1 && GetTop(pnd,rs)){DestroyStack(pst);DestroyStack(pnd);return 1;}//否则 return 0else{return 0;}}//10.⽤户交互函数void treatment(){char buffer[100];//⽤户输⼊的字符串(算式)cal calstr[50];//计算⽤的数组double rs = 0;//计算结果printf("Enter your equation:");gets(buffer);//让⽤户输⼊算式buffer//⽤户不输⼊"exit"就不退出while (!(buffer[0]=='e' && buffer[1]=='x' && buffer[2]=='i' && buffer[3]=='t')){//检查buffer中字符君合法,成功将buffer转化为⽤于计算的calstr数组,成功计算出结果存⼊rsif (CheckStr(buffer) && resolu(buffer,calstr) && result(calstr,&rs)){printf("\n%lf\n",rs);}else{printf("\nError!\n");}printf("Enter \"exit\"to quit");printf("\nEnter your equation:");gets(buffer);//再次让⽤户输⼊算式}printf("\nbye\n");}//11.主函数int main(){treatment();}参考⽂献链接如下[参考⽂献]()。
C语言简易计算器的实现
C语言简易计算器的实现C语言简易计算器是一种用于进行基本数学运算的程序。
实现一个简易计算器的关键是要能够解析用户输入的数学表达式,并将其转化为计算机可以理解的形式,然后进行计算,并输出结果。
下面是一个大约1200字以上的示例实现。
```c#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <ctype.h>#define MAX_SIZE 100//定义操作符的优先级int getPriority(char op)if (op == '+' , op == '-')return 1;else if (op == '*' , op == '/')return 2;elsereturn 0;//进行四则运算int calculate(int a, int b, char op)switch (op)case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': return a / b;default: return 0;}//将中缀表达式转换为后缀表达式void infixToPostfix(char* infixExp, char* postfixExp) char stack[MAX_SIZE];int top = -1;int j = 0;for (int i = 0; infixExp[i] != '\0'; i++)if (isdigit(infixExp[i])) { // 数字直接输出到后缀表达式while (isdigit(infixExp[i]))postfixExp[j++] = infixExp[i++];}postfixExp[j++] = ' ';i--;}else if (infixExp[i] == '(') { // 左括号压入栈stack[++top] = infixExp[i];}else if (infixExp[i] == ')') { // 右括号弹出栈内所有操作符并输出到后缀表达式,直到遇到左括号while (top != -1 && stack[top] != '(')postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}top--; // 弹出栈顶的左括号}else { // 操作符while (top != -1 && getPriority(stack[top]) >=getPriority(infixExp[i]))postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';stack[++top] = infixExp[i];}}while (top != -1) { // 将栈内剩余操作符弹出并输出到后缀表达式postfixExp[j++] = stack[top--];postfixExp[j++] = ' ';}postfixExp[j] = '\0';//计算后缀表达式的值int evaluatePostfix(char* postfixExp)char stack[MAX_SIZE];int top = -1;for (int i = 0; postfixExp[i] != '\0'; i++)if (isdigit(postfixExp[i])) { // 数字压入栈int num = 0;while (isdigit(postfixExp[i]))num = num * 10 + (postfixExp[i++] - '0');stack[++top] = num;i--;}else if (postfixExp[i] == ' ')continue;}else { // 操作符,弹出栈顶的两个数进行计算,并将结果压入栈int b = stack[top--];int a = stack[top--];int result = calculate(a, b, postfixExp[i]);stack[++top] = result;}}return stack[top];int maichar infixExp[MAX_SIZE];printf("请输入中缀表达式:");fgets(infixExp, sizeof(infixExp), stdin); // 读取用户输入//将中缀表达式转换为后缀表达式char postfixExp[MAX_SIZE];infixToPostfix(infixExp, postfixExp);printf("后缀表达式为:%s\n", postfixExp);//计算后缀表达式的值并输出int result = evaluatePostfix(postfixExp);printf("计算结果为:%d\n", result);return 0;```这个简易计算器的实现基于栈的数据结构。
C语言堆栈计算器
#include"stdafx.h"#include<string.h>#include<ctype.h>#include<malloc.h>// malloc()等#include<limits.h>// INT_MAX等#include<io.h>// eof()#include<math.h>// floor(),ceil(),abs()#include<process.h>// exit()#include<iostream>// cout,cin// 函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为,故去掉此行typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE#define STACK_INIT_SIZE 100#define STACKINCREMENT 10//*************************************************************************** //栈的储存结构typedef struct{//运算符栈char *base;char *top;int stacksize;}SqStack1;typedef struct{//运算数栈float *base;float *top;int stacksize;}SqStack2;//*************************************************************************** //以下是运算符栈的基本操作函数Status InitStack(SqStack1 &S){//初始化一个栈S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}//InitStackStatus DestroyStack(SqStack1 &S){//销毁栈Sfree(S.top);free(S.base);return OK;}//DestroyStackchar GetTop(SqStack1 S){//若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;return *(S.top-1);}//GettopStatus Push(SqStack1 &S,char e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加储存空间S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}//PushStatus Pop(SqStack1 &S,char &e){//若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;e=*(--S.top);return OK;}//Pop//*************************************************************************** //以下是运算数栈的基本操作函数Status InitStack(SqStack2 &S){//初始化一个栈S.base=(float *)malloc(STACK_INIT_SIZE*sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}//InitStackStatus DestroyStack(SqStack2 &S){//销毁栈Sfree(S.top);free(S.base);return OK;}//DestroyStackfloat GetTop(SqStack2 S){//若栈不空,则返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;return *(S.top-1);}//GettopStatus Push(SqStack2 &S,float e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加储存空间S.base=(float *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(float));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}//PushStatus Pop(SqStack2 &S,float &e){//若栈不空,则删除S的栈顶元素,用e返回其值;并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;e=*(--S.top);return OK;}//Pop//*************************************************************************** //以下是相关的运算符判断函数char Precede(char A,char B){//比较运算符A, B的优先关系,A,B的范围仅限于'+','-','*','/','^','(',')','=' //返回'>','<','='switch(A){case'+':switch(B){case'+':return'>';case'-':return'>';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'-':switch(B){case'+':return'>';case'-':return'>';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'*':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0);}case'/':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'<';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'^':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'>';case'(':return'<';case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'(':switch(B){case'+':return'<';case'-':return'<';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':return'=';case'=':printf("表达式错误!\n");exit(0);default:printf("表达式错误!\n");exit(0); }case')':switch(B){case'+':return'>';case'-':return'>';case'*':return'>';case'/':return'>';case'^':return'>';case'(':printf("表达式错误!\n");exit(0);case')':return'>';case'=':return'>';default:printf("表达式错误!\n");exit(0); }case'=':switch(B){case'+':return'<';case'-':return'<';case'*':return'<';case'/':return'<';case'^':return'<';case'(':return'<';case')':printf("表达式错误!\n");exit(0);case'=':return'=';default:printf("表达式错误!\n");exit(0);}default:printf("表达式错误!\n");exit(0);}}//PrecedeStatus InOP(char c){//判断c是否是运算符,是则返回TRUE,否则返回FALSEswitch(c){case'+':return TRUE;case'-':return TRUE;case'*':return TRUE;case'/':return TRUE;case'^':return TRUE;case'(':return TRUE;case')':return TRUE;case'=':return TRUE;default:return FALSE;}}//InOP//***************************************************************************float Operate(float a,char theta,float b){switch(theta){case'+':return a+b;case'-':return a-b;case'*':return a*b;case'/':if(b==0){printf("分母不能为!\n");exit(0);}else return a/b;case'^':if(a==0&&b<=0){printf("0的指数必须大于!\n");exit(0);}else return (float)pow(a,b);default:printf("表达式错误!\n");exit(0);}//OperateStatus EvaluateExpression(){//算术表达式求值char c,x,theta,prec;//c是每次读取的字符,x是存放脱括号后的多余的括号,theta是运算符,prec是c的前一个字符float a,b,result;//a、b是每次从运算数栈中取出的要进行运算的数,result存放最终结果float cc,flag,ii,minus=1;//cc存放由字符串转化而来的浮点数,flag用于标记是否已读取过小数点,//ii存放小数部分需要缩小的倍数,minus用于记录该数前是否有负号SqStack1 OPTR;SqStack2 OPND;InitStack(OPTR);InitStack(OPND);Push(OPTR,'=');prec='=';scanf("%c",&c);while(c!='='||GetTop(OPTR)!='='){cc=0;flag=0;ii=10;if(c=='-'&&(prec=='='||prec=='(')){minus=-1;prec=c;scanf("%c",&c);}//若某“-”前面是“=”(第一个符号就是“-”)或“(”,则此为负号,不是减号elseif(!InOP(c)){while(!InOP(c)){if(c>=48&&c<=57){if(flag==0)cc=cc*10+c-48;//小数点之前else if(flag==1){cc=cc+(c-48)/ii;ii*=10;}//小数点之后else {printf("小数点错误!\n");exit(0);}//小数点有错}else if(c=='.')flag++;//读到小数点else {printf("表达式错误!\n");exit(0);}prec=c;scanf("%c",&c);}cc*=minus;minus=1;Push(OPND,cc);}//不是运算符则进OPND栈elseswitch(Precede(GetTop(OPTR),c)){case'<':Push(OPTR,c);prec=c;scanf("%c",&c);break;//栈顶元素优先级低case'=':Pop(OPTR,x);prec=c;scanf("%c",&c);break;//脱括号并接收下一字符case'>'://退栈并将运算结果入栈Pop(OPTR,theta);Pop(OPND,b);Pop(OPND,a);Push(OPND,Operate(a,theta,b));break;}result=GetTop(OPND);printf("%f\n",result);//DestroyStack(OPTR);//DestroyStack(OPND);return OK;}//EvaluateExpressionvoid main(){printf(" **********************\n");printf(" * 欢迎使用计算器! *\n");printf(" **********************\n");printf("请输入表达式,以“=”结束:\n");printf("(支持实数间的加(+)、减(-)、乘(*)、除(/)、乘方(^)、单目减(-)运算)\n"); EvaluateExpression();exit (0);}。
C语言简单计算器原理——表达式求值(采用逆波兰表达式和栈结合)
C语⾔简单计算器原理——表达式求值(采⽤逆波兰表达式和栈
结合)
表达式的求解的关键是将其转换成逆波兰表达式(即后缀表达式,如1+2*3它的逆波兰表达式为123*+),在后缀表达式中已经考虑了运算符的优先级,
没有括号,只有操作数和运算符。
算术表达式转换成后缀表达式⽅法如下:
依次从键盘输⼊表达式的字符ch,对于每个ch:
(1)若ch为数字则直接将其放⼊后缀数组exp中并以#号标记数值串结束。
(2)若ch为"(",则直接将其压⼊字符栈op中。
(3)若ch为")",则将栈中"("以前的字符依次全部删除并将其放⼊后缀数组exp中,然后再将字符ch放⼊字符栈op中。
(4)若ch为"+"."-",则将栈中"("以前的运算符依次全部删除并将其放⼊后缀数组exp中,然后再将ch放⼊op栈中。
(5)若ch为"*"."/",则将栈顶连续的"*"."/"删除,并放⼊后缀数组exp中,然后将ch放⼊op栈中。
(6)若字符串str扫描完毕,则将栈中所有运算符删除并放⼊后缀数组exp,最后在后缀数组exp中便可得到后缀表达式。
在对后缀表达式求值时要⽤到⼀个数值栈st,在后缀数组exp中从头开始扫描,若是数字则将其放⼊数值栈中,
若遇到字符就进⾏两次退栈,并将运算结果再放⼊栈中,如此重复下去,最后当后缀数组扫描完后数值栈st的栈顶元素便是所要求的表达式的值。
用C实现计算器
link top;//去栈顶元素
if(stack!=NULL)
{
top=stack;
stack=stack->next;
*num=top->date;
free(top);
return stack;
}
else
*num=0;
}
//判断栈是否为空
number=pull(number,&sum);
cout<<expression<<"="<<sum<<endl;
}
{ while(symble->date!='(')
{ number=pull(number,&num1);
number=pull(number,&num2);
symble=pull(symble,&sym);
number=push(number,tuo_result(sym,num1,num2),-1);
int position=0;//表达式的位置
int sym=0;//运算符
int num1=0;//后操作数
int num2=0;//前操作数
int sum=0;//运算结果
cout<<"请输入表达式:"<<endl;
gets(expression);
while(expression[position]!='\0' && expression[position]!='\n')
if(!empty(symble))//判断是否为空
C语言数据结构栈计算器的实现 课题设计报告书
目录1、课程设计任务 (1)2、需求分析 (1)3、概要设计………………………………………………………………………………1~24、详细设计………………………………………………………………………………3~55、小结 (5)课程设计任务·利用堆栈设计一个计算器。
需求分析·首先,以字符列的形式,从终端输入语法正确、不含变量的整数表达式。
利用已知的运算符优先关系,实现对算术四则混合运算表达式的求值。
·对该程序而言,主要的利用应是栈,并将运算的先后步骤经分析后实现为简单运算。
·不同于单纯表达式的运算,计算器有直接计算最近输入数据的特性,故只需一个栈对其进行操作数和操作符的存储即可。
·除通常的四则运算(加减乘除)外,计算器还应有求相反数、百分数、开根、倒数等功能。
概要设计·由于运算符有优先级别之差,所以一个表达式的运算不可能总是从左至右的循序执行。
每次操作的数据或运算符都是最近输入的,这与栈的特性相吻合,故本程序借助栈来实现按操作符的优先级完成表达式的求值计算。
算法概要:1、栈的抽象数据定义:ADT SqStack{数据对象:D={a i| a i∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<a i-1,a i>| a i-1,a i∈D,i=1,2,3,……,n}约定其中a i端为栈底,a n端为栈顶。
2、栈的实现和操作集合:为不同于C# 编译库中自带的类库Stack<T>,这里使用CStack<T>进行区分。
classCStack<T>{privateintp_index;privateArrayList list;public CStack()/*初始化*/{list = new ArrayList();p_index = -1;}publicint Count{get{returnlist.Count;}}public void Push(object item)/*入栈*/{list.Add(item);p_index++;}public object Pop()/*出栈*/{objectobj = list[p_index];list.RemoveAt(p_index);p_index--;returnobj;}}3、运算:计算器在输入一个操作符后,文本框内的数据会清空,故只需一个栈即可完成相应的运算。
简易计算器_堆栈实现
#include<iostream>#include<stack>#include<queue>#include<string>#include<cctype>#include<stdio.h>#pragmawarning(disable:4996)usingnamespace std;class Expression{public:void setExpression(); //从屏幕获取一行计算式子void calculationResult(); //计算出结果,并输出private:void transformation(); //将中缀表达式转换成后缀表达式stack<string> stringStack; //栈queue<string> stringQueueMiddle; //存储中缀表达式的队列queue<string> stringQueueBack; //存储后缀表达式的队列};void Expression::setExpression(){char ch[200];string str; //获取屏幕的表达式string strNumber; //暂时存储数字string strSymbol; //暂时存储运算符int i = 0;cout <<"请输入一个表达式(不需要输入=,请不要输入无谓的字符隔开,比如空格):"<<endl;cout <<"\t";cin.getline(ch, 200);str = ch;for (i = 0; i < str.size(); i++) {if (str[i]>= '0'&&str[i]<= '9') {strNumber += str[i];}else {stringQueueMiddle.push(strNumber); //将数字添加到队列strNumber.clear(); //清空字符串strSymbol += str[i];stringQueueMiddle.push(strSymbol); //将符号添加到队列strSymbol.clear(); //清空字符串}}//将最后一个数字添加到队列stringQueueMiddle.push(strNumber); //将数字添加到队列strNumber.clear(); //清空字符串transformation();}void Expression::transformation(){int i = 0;for (; !stringQueueMiddle.empty(); stringQueueMiddle.pop()) {if (isdigit(stringQueueMiddle.front()[0])) //判断该字符串的第一个字符是否为数字stringQueueBack.push(stringQueueMiddle.front()); //纯数字则将该字符串添加到后缀表达式队列elseif (stringStack.empty() || '(' == stringQueueMiddle.front()[0]) stringStack.push(stringQueueMiddle.front()); //如果栈空或者遇到 (,则直接进栈elseif ('+' == stringQueueMiddle.front()[0] || '-' == stringQueueMiddle.front()[0]) {if (!stringStack.empty()&&'*'==stringStack.top()[0]||'/' == stringStack.top()[0]) { //栈不空,则栈中有 */ 则出栈//栈中只要有连续的 +-*/就出栈,且栈不能为空,遇到(也不出栈for (; !stringStack.empty()&&'('!= stringStack.top()[0]; stringStack.pop())stringQueueBack.push(stringStack.top()); // */ 进入后缀表达式队列}elseif (!stringStack.empty() &&'+' == stringStack.top()[0] || '-' == stringStack.top()[0]) { //如果遇到同等级的运算符,则先出栈再进栈stringQueueBack.push(stringStack.top());stringStack.pop(); //栈顶出栈}stringStack.push(stringQueueMiddle.front()); //+-优先级低,直接进栈}elseif ('*' == stringQueueMiddle.front()[0] || '/' == stringQueueMiddle.front()[0]) {if (!stringStack.empty() &&'*' == stringStack.top()[0] || '/' == stringStack.top()[0]) { //栈不空,则栈中有 */ 则出栈stringQueueBack.push(stringStack.top()); //进后缀表达式的队stringStack.pop();}stringStack.push(stringQueueMiddle.front()); //进栈}elseif (')' == stringQueueMiddle.front()[0]) { //遇到右括号,则左括号之前的运算符都弹出for (; '(' != stringStack.top()[0]; stringStack.pop())stringQueueBack.push(stringStack.top()); //运算符依次进入后缀表达式队列stringStack.pop(); //弹出 (}}for (; !stringStack.empty();stringStack.pop()){ // 中缀表达式扫描完毕,则栈中的所有运算符弹出if('('!=stringStack.top()[0])stringQueueBack.push(stringStack.top()); //将栈中的运算符添加到后缀表达式队列}}void Expression::calculationResult(){double back=0.0; //记录第一个从栈顶弹出来的元素double front=0.0; //记录第二个从栈顶弹出来的元素double result=0.0; //记录运算结果char ch[100];string str;for (; !stringQueueBack.empty(); stringQueueBack.pop()) {if (isdigit(stringQueueBack.front()[0])) //判断该字符串的第一个字符是否为数字stringStack.push(stringQueueBack.front()); //纯数字则将该字符串进栈else { //遇到运算符switch (stringQueueBack.front()[0]){case'+':back = atof(stringStack.top().c_str()); //弹出第一个栈顶元素stringStack.pop();front = atof(stringStack.top().c_str()); //弹出第二个栈顶元素stringStack.pop();result = front + back;sprintf(ch, "%lf", result); //将浮点数转换成字符串str = ch;stringStack.push(str);break;case'-':back = atof(stringStack.top().c_str()); //弹出第一个栈顶元素stringStack.pop();front = atof(stringStack.top().c_str()); //弹出第二个栈顶元素stringStack.pop();result = front - back;sprintf(ch, "%lf", result); //将浮点数转换成字符串str = ch;stringStack.push(str);break;case'*':back = atof(stringStack.top().c_str()); //弹出第一个栈顶元素stringStack.pop();front = atof(stringStack.top().c_str()); //弹出第二个栈顶元素stringStack.pop();result = front * back;sprintf(ch, "%lf", result); //将浮点数转换成字符串str = ch;stringStack.push(str);break;case'/':back = atof(stringStack.top().c_str()); //弹出第一个栈顶元素stringStack.pop();front = atof(stringStack.top().c_str()); //弹出第二个栈顶元素stringStack.pop();result = front / back;sprintf(ch, "%lf", result); //将浮点数转换成字符串str = ch;stringStack.push(str);break;default:break;}}}cout <<"\t="<< stringStack.top()<<endl; //栈只剩下一个结果,直接输出即可}int main(void){Expression e;e.setExpression();e.calculationResult();return 0;}。
借助栈完成运算表达式的求值c语言
一、概述在计算机科学中,栈是一种非常重要的数据结构,它具有“先进后出”的特点,能够很好地辅助实现算法和表达式的求值。
在C语言中,我们可以借助栈这种数据结构来完成对运算表达式的求值,从而实现计算功能。
本文将介绍如何在C语言中利用栈完成运算表达式的求值。
二、栈的基本概念1. 栈的定义栈是一种线性结构,它具有两个基本的操作:入栈(push)和出栈(pop)。
栈的特点是只允许在栈顶进行操作,即每次只能操作最后一个插入到栈中的元素。
这种先进后出的结构使得栈非常适合用来处理递归、表达式求值等问题。
2. 栈的实现在C语言中,我们可以通过数组或链表来实现栈。
数组实现的栈叫做顺序栈,链表实现的栈叫做链式栈。
对于运算表达式的求值来说,我们可以选择数组来实现栈。
栈的结构可以定义如下:```c#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];int top;} Stack;```这样我们就定义了一个包含数组和栈顶指针的栈结构类型。
三、运算表达式的求值1. 中缀表达式在数学中,我们通常使用中缀表达式来表示运算式,例如:1 + 2 * 3。
这种表达式的书写方式是运算符位于操作数之间。
在计算机中,中缀表达式不太方便进行求值,因此我们需要将中缀表达式转换为后缀表达式来进行计算。
2. 后缀表达式后缀表达式又称为逆波兰表达式,它的特点是运算符位于操作数之后,比如:1 2 3 * +。
后缀表达式的求值非常简单,只需要从左到右遍历表达式,遇到操作数就入栈,遇到运算符就弹出栈顶的两个操作数进行运算,然后将结果再入栈,直到表达式结束。
3. 栈完成后缀表达式的求值我们可以利用栈来完成后缀表达式的求值。
具体步骤如下:(1)创建一个空栈(2)从左到右遍历后缀表达式(3)如果遇到操作数,则入栈(4)如果遇到运算符,则弹出栈顶的两个操作数进行运算,然后将结果入栈(5)遍历结束后,栈中剩下的元素就是表达式的值四、示例代码下面是一个简单的示例代码,演示了如何利用栈完成后缀表达式的求值:```c#include <stdio.h>#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];int top;} Stack;void initStack(Stack *s) {s->top = -1;}void push(Stack *s, int value) { if (s->top < MAX_SIZE - 1) { s->data[++s->top] = value; } else {printf("Stack is full\n");}}int pop(Stack *s) {if (s->top >= 0) {return s->data[s->top--]; } else {printf("Stack is empty\n"); return -1;}}int evaluatePostfix(char *exp) { Stack s;initStack(s);int i = 0;while (exp[i] != '\0') {if (isdigit(exp[i])) {push(s, exp[i] - '0');} else {int op2 = pop(s);int op1 = pop(s);switch (exp[i]) {case '+':push(s, op1 + op2);break;case '-':push(s, op1 - op2);break;case '*':push(s, op1 * op2);break;case '/':push(s, op1 / op2);break;default:printf("Invalid operator\n"); return -1;}}i++;}return pop(s);}int m本人n() {char exp[] = "12+3*";int result = evaluatePostfix(exp);printf("Result: d\n", result);return 0;}```五、总结本文介绍了利用栈来完成C语言中运算表达式的求值。
基于堆栈实现计算器
基于堆栈实现计算器周项⽬作业憋两天没有解决问题,只能返回⽼师代码重新分析。
常识解决问题。
以下代码全部摘⾃培训班⽼师。
基于堆栈的⽅法,实现计算器。
代码分析:#_*_coding:utf-8_*_import redef is_symbol(element):#定义运算符函数res=Falsesymbol=['+','-','*','/','(',')']if element in symbol:res=Truereturn resdef priority(top_sym,wait_sym):#定义运算优先级函数# print('from the priotry : ',top_sym,wait_sym)level1=['+','-']level2=['*','/']level3=['(']level4=[')']#运算符栈栈顶元素为+-if top_sym in level1:# if wait_sym in level1:# return '>'# elif wait_sym in level2: # top_sym='-' wait_sym='*'# return '<'# elif wait_sym in level3: # top_sym='-' wait_sym='('# return '<'# elif wait_sym in level4: # top_sym='-' wait_sym=')'# return '>'# else:# return '>'if wait_sym in level2 or wait_sym in level3:return'<'else:return'>'#运算符栈栈顶元素为*/elif top_sym in level2:# if wait_sym in level1:# top_sym='*' wait_sym='+'# return '>'# elif wait_sym in level2:# top_sym='*' wait_sym='*'# return '>'# elif wait_sym in level3:# top_sym='*' wait_sym='('# return '<'# elif wait_sym in level4:# top_sym='*' wait_sym=')'# return '>'# else:# return '>'if wait_sym in level3:return'<'else:return'>'#运算符栈栈顶元素为(elif top_sym in level3:if wait_sym in level4: #右括号)碰到了(,那么左括号应该弹出栈return'='else:return'<'#只要栈顶元素为(,等待⼊栈的元素都应该⽆条件⼊栈#运算符栈栈顶元素为),右括号与左括号是成对出现,当出现右括号时,不会将括号⼊栈,所以不⽤考虑此情况def calculate(num1,symbol,num2):#定义计算函数。
C++利用栈实现计算器
C++利⽤栈实现计算器后缀表达式,⼜称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后⾯,所有的计算按运算符出现的顺序,严格从左向右进⾏,所以不需要算符优先级,这对我们编写计算器来说很好实现⽐如给定⼀个中缀表达式:1 + 3 * 5 – ( 7 / 9 )其后缀表达式应为:1 3 5 * + 7 9 / -⾸先要理解如何进⾏转换,先按照运算优先级对其加上括号1 + 3 * 5 – ( 7 / 9 ) = ( (1 + (3 * 5 ) ) – ( 7 / 9 ) )然后依次把优先级⾼的括号转为后缀((1+(3*5)) – (7/9))--> ((1 + (35*)) – (79/))--> ((1 (35*)+) – 79/)--> (135*+)(79/)---> 135*+79/-整体步骤中缀表达式转后缀表达式计算后缀表达式第⼀步:中缀表达式转后缀表达式⾃左向右读⼊中缀表达式1. 数字时,加⼊后缀表达式;2. 运算符:-若为 ‘(’,⼊栈-若为 ‘)’,则依次把栈中的的运算符加⼊后缀表达式中,直到出现’(’,从栈中删除’(’-若为除括号外的其他运算符,当其优先级⾼于除’('以外的栈顶运算符时,直接⼊栈。
否则从栈顶开始,依次弹出⽐当前处理的运算符优先级⾼和优先级相等的运算符,直到⼀个⽐它优先级低的或者遇到了⼀个左括号为⽌,然后将其⾃⾝压⼊栈中(先出后⼊)。
3. 当扫描的中缀表达式结束时,栈中的的所有运算符出栈;具体图⽰:第⼆步计算后缀表达式建⽴⼀个栈S 。
从左到右读表达式,如果读到操作数就将它压⼊栈S中,如果读到n元运算符(即需要参数个数为n的运算符)则取出由栈顶向下的n项按操作数运算,再将运算的结果代替原栈顶的n项,压⼊栈S中。
如果后缀表达式未读完,则重复上⾯过程,最后输出栈顶的数值则为结束。
简⾔之:1. 从左到右读表达式2. 遇到操作数压⼊栈中3. 遇到操作符取并弹出栈顶n个元素,(n取决于操作符是n元操作符),计算结果压⼊栈中4. 后缀表达式读完,当前栈顶元素及为结果代码如下#include <iostream>#include<stack>#include <sstream>#include<stdlib.h>using namespace std;double CalSuffix(string suffix){double result;stack<double> number;int i = 0,j;int n=0;//判断是否为数字string current;while(suffix[i]!='#'){isNum=0;if(suffix[i]=='|'){for(j=i+1;; j++){if(suffix[j]=='|')break;if(suffix[j]=='#')break;}//获取|A|之间元素for(int k=i+1; k<j; k++){current+=suffix[k];}//判断是否为数值for(int k=0; k<current.size(); k++){if(current[k]>=48 && current[k]<=57)//数字{//strinf转doubleistringstream iss(current);double num;iss >> num;number.push(num);isNum = 1;break;}}if(isNum!=1){double n2 = number.top();number.pop();double n1 = number.top();number.pop();if(current=="+"){number.push(n1+n2);}else if(current=="-"){number.push(n1-n2);}else if(current=="*"){number.push(n1*n2);}else if(current=="/"){number.push(n1/n2);}}current="";//清空当前字符串;}i++;}if(number.size()!=1)cout<<"输⼊有误"<<endl;elsereturn number.top();}int Priority(char operate)//栈中优先级{switch(operate){case '+':case '-':return 2;case '*':case '/':return 3;case '(':return 0;}}string Infix2Suffix(string Infix){stack<char> operate;string Suffix = " ";//初始化后缀表达式char currentOp;int negative;int i = 0,j = 0;//i为中缀当前指向 j为后缀当前指向while(Infix[i]!='\0'){if(i+1!='\0')negative = 0;if(Infix[i]>=48 && Infix[i]<=57) //判断数字{Suffix[j++] = '|';//j是后缀表达索引Suffix[j++] =Infix[i];//存储当前数字并指向下⼀个while(Infix[++i]>=48 && Infix[i]<=57) //整数部分{Suffix[j++] =Infix[i];}if(Infix[i]=='.') //是⼩数{Suffix[j++]='.';i+=1;//中缀索引往后移while(Infix[i]>=48 && Infix[i]<=57) //⼩数部分{Suffix[j++] =Infix[i];i+=1;}}}else if(Infix[i]=='(')//如果读⼊(,因为左括号优先级最⾼,因此放⼊栈中,但是注意,当左括号放⼊栈中后,则优先级最低。
C++实现简易计算器功能
C++实现简易计算器功能本⽂实例为⼤家分享了C++实现简易计算器功能的具体代码,供⼤家参考,具体内容如下介绍介绍:仅⽀持⾃然数间的+ - * /操作,并没有括号。
实现:利⽤栈实现存储运算数以及运算符。
流程1、输⼊:string exp2、对EXP进⾏处理:数字⼊数栈,运算符⼊字符栈。
1)栈空,字符⼊栈2)栈⾮空栈顶运算级别> =当前字符运算级,取栈顶运算符并出栈两个数,计算,结果⼊数栈 3)字符⼊栈3、对字符栈检测,⾮空时进⾏计算4、输出:结果。
实现const int MAXSIZE = 100;//栈的最⼤⼤⼩template<typename T>class Stack {private:T data[MAXSIZE];int top;public:Stack();void Push(const T& val);T Top()const;void Pop();void Clear();bool IsFull()const;bool IsEmpty()const;};template<typename T>Stack<T>::Stack() {top = -1;}template<typename T>void Stack<T>::Push(const T& val) {if (IsFull()) exit(1);//未满data[++top] = val;}template<typename T>T Stack<T>::Top()const {if (IsEmpty()) exit(1);//⾮空return data[top];}template<typename T>void Stack<T>::Pop() {if (IsEmpty()) exit(1);--top;}template<typename T>void Stack<T>::Clear() {top = -1;}template<typename T>bool Stack<T>::IsFull()const {return top == MAXSIZE - 1;}template<typename T>bool Stack<T>::IsEmpty()const {return top == -1;}class Calculator {private:Stack<int> num;Stack<char> ch;//运算符bool GetTwoOperands(int& left,int& right); void Compute();void Deal(const string& exp);public:Calculator() {}void Run();void Clear();//清空数栈以及字符栈};void Calculator::Run() {string exp;cin >> exp;Deal(exp);while ( !ch.IsEmpty()) {Compute();}cout << "结果:" << num.Top() << endl;Clear();}void Calculator::Deal(const string& exp) {int i(0), n(exp.length());bool last = false;while (i < n&&exp[i] != '=') {if (exp[i] >= '0'&&exp[i] <= '9') {if (last) {int x = num.Top() * 10 + (exp[i] - '0'); num.Pop();num.Push(x);}else {num.Push(exp[i] - '0');last = true;}}else {last = false;while (!ch.IsEmpty()) {int i1 = f(ch.Top());int i2 = f(exp[i]);if (i1 >= i2)Compute();elsebreak;}ch.Push(exp[i]);}++i;}}计算:void Calculator::Compute() {bool b;int left, right;b = GetTwoOperands(left, right);if (!b) {cout << "Error\n";Clear();}else {char op = ch.Top();ch.Pop();switch (op) {case '+':left += right;break;case '-':left -= right;break;case '*':left *= right;break;case '/':if (right == 0) {cout << "Error\n";Clear();return;}left /= right;break;}num.Push(left);}}// 将运算符优先级转为整数,便于⽐较int f(const char& c) {if (c == '+' || c == '-') return 1;else return 2;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
栈应用之中缀表达式计算MFC实现(计算器核心)
栈应⽤之中缀表达式计算MFC实现(计算器核⼼)⼤家好,我是⼩鸭酱,博客地址为:⽀持⼩数、阶乘、乘⽅、加减乘除、括号优先级运算,美化输出结果(显⽰结果末尾没有多余的0)void CCaculator_LittleduckDlg::OnBnClickedButton12() // 在这⾥进⾏运算最关键的代码{// TODO: 在此添加控件通知处理程序代码CString editText;GetDlgItemText(IDC_EDIT2, editText);double ans = 0;CString CString_ans("Sorry, but I do not know.");int noans = 0;CString operators ("$"); // 运算符栈int operators_len = 1;double numbers[100]={0}; // 数字栈int numbers_len = 0;const char pri[9][9] = { // [栈顶][当前] = 表⽰抵销 >表⽰计算 <表⼊栈 " "为匹配不成功//------------当前运算符// + - * / ^ ! ( ) $// 0 1 2 3 4 5 6 7 8/* + 0*/'>','>','<','<','<','<','<','>','>',/* 栈 - 1*/'>','>','<','<','<','<','<','>','>',/* 顶 * 2*/'>','>','>','>','<','<','<','>','>',/* 运 / 3*/'>','>','>','>','<','<','<','>','>',/* 算 ^ 4*/'>','>','>','>','>','<','<','>','>',/* 符 ! 5*/'>','>','>','>','>','>',' ','>','>',/* ( 6*/'<','<','<','<','<','<','<','=',' ',/* ) 7*/' ',' ',' ',' ',' ',' ',' ',' ',' ',/* $ 8*/'<','<','<','<','<','<','<',' ','='};CString tail("$");editText += tail;CString blank(" ");CString mynum("0123456789.");CString myoper("+-*/^!()$");int digit = 0; // 当前数字位数int point = 0; // ⼩数点个数for(int i = 0; i < editText.GetLength(); ++i) // 开始处理这个字符串{if( editText[i] == blank ) // 空⽩则略过{continue;}else if(editText[i] == mynum[0] || editText[i] == mynum[1] ||editText[i] == mynum[2] || editText[i] == mynum[3] ||editText[i] == mynum[4] || editText[i] == mynum[5] ||editText[i] == mynum[6] || editText[i] == mynum[7] ||editText[i] == mynum[8] || editText[i] == mynum[9] ) // 数字处理{++ digit;if (digit > 1) // 数字位数⼤于1,则数字栈顶数字出栈,重新整理再⼊栈{temp = editText[i];numbers[ numbers_len - 1] = numbers[ numbers_len - 1] * 10 + _wtof(temp) ;if(point > 0)++ point; // 记录⼩数的位数}else // 数字⼊栈{++ numbers_len;CString temp = blank;temp = editText[i];numbers[numbers_len -1] = _wtof(temp);//* (numbers + numbers_len - 1) = atof(temp);}}else if (editText[i] == mynum[10]){point = 1;}else // 最重要的运算 = 表⽰抵销 >表⽰计算 <表⼊栈 " "为匹配不成功{digit = 0;if (point > 0){point --;for(int tem = 0; tem < point; ++ tem)numbers[ numbers_len - 1] = numbers[ numbers_len - 1] / 10; // 刚刚⼊栈的那个数调整其⼩数点point = 0;}CString temp = blank;temp = editText[i]; //当前运算符int top = 0, cur = 0;for(int a = 0; a < myoper.GetLength(); ++ a){if( myoper[a] == temp ){cur = a;}if( myoper[a] == operators[operators_len - 1] ){top = a;}}char cpri = pri[top][cur];if(cpri == '<')//运算符⼊栈{++ operators_len;operators += temp;}if(cpri == '>') // 计算注意i的值在下⼀次不变记得取出运算符{if(top < 5 && numbers_len < 2){noans = 1;break;}if(numbers_len > 1 && top < 5){// 取出两个数double number1, number2, number3 = 1;number1 = numbers[ numbers_len - 2 ];number2 = numbers[ numbers_len - 1 ];// 进⾏运算switch (top)case 0: // + 运算number3 = number1 + number2;break;case 1: // - 运算number3 = number1 - number2;break;case 2: // * 运算number3 = number1 * number2;break;case 3: // / 运算number3 = number1 / number2;break;case 4: // ^ 运算for(int te = 0; te < number2; ++ te){number3 *= number1;}break;}// 把结果放回栈顶-- numbers_len;numbers[ numbers_len - 1 ] = number3;////丢掉最后⼀个运算符-- operators_len;CString temp11("");for(int l = 0; l < operators_len; ++ l){temp11 += operators[l];}operators = temp11;}if(top == 5 && numbers_len > 0) // ! 运算取出⼀个数做阶层运算并把结果放回栈中{double number2, number3 = 1;number2 = numbers[ numbers_len - 1 ];-- operators_len;CString temp11("");for(int l = 0; l < operators_len; ++ l) // 丢掉最后⼀个运算符{temp11 += operators[l];}operators = temp11;for (int te = 1; te <= number2; te++){number3 *= te;}if(number2 == 0){number3 = 1;}numbers[ numbers_len - 1 ] = number3;}-- i;}if(cpri == '=') // 运算符抵销{-- operators_len;CString temp11("");for(int l = 0; l < operators_len; ++ l) // 丢掉最后⼀个运算符temp11 += operators[l];}operators = temp11;}if(cpri == ' ') // 运算符不匹配终⽌运算并显⽰Sorry, but I do not know. {noans = 1;break;}}}if (numbers_len == 1 && operators_len == 0 && noans == 0){ans = numbers[ numbers_len - 1];CString_ans.Format(L"%f", ans);int point = 0;CString cpoint(".");CString blank("0");for (int i = 0; i < CString_ans.GetLength(); i++){if(CString_ans[i] == cpoint){point = i;break;}}if(point > 0){for (int i = CString_ans.GetLength() - 1; i >= point; i--){if(CString_ans[i] != blank){CString mystr("");for(int k = 0; k < i; ++k){mystr += CString_ans[k];}if(i > point){mystr += CString_ans[i];}CString_ans = mystr;break;}}}}if(noans == 1 || numbers_len > 1 || operators_len > 0){CString_ans = "Sorry, but I do not know.";}SetDlgItemText(IDC_EDIT2, CString_ans);}。
利用堆栈实现的计算器(代码)
class Stack1
{
private:
char *top;
char *base;
int stacksize;
int size;
public:
Stack1();
~Stack1();
bool IsFull();
bool IsEmpty();
void Push(char e);
}u;
char c;
};
bool check(char ch[])
{
if(ch[0]<'0'||ch[0]>'9')
return fΒιβλιοθήκη lse;elsereturn true;
}
double exchange(char str[],int dot)
{ //将字符串转化为小数
int i,zs;double xs;double re;
数据结构课程实验利用堆栈实现简单计算器代码共4个文件maincc文件includeincludestackhincludeopretorhusingnamespacestd
数据结构课程实验(利用堆栈实现简单计算器)
代码共4个文件
//文件
#include <iostream>
#include "stack.h"
{
int i=0,j=0,k=0,dot=-1;
char ss[20];
double nn=0;
double x=0,y=0;
char e='0';
struct evaluation eval[20];
c++堆栈计算器
《数据结构》课程设计报告专业:信息管理与信息系统班级:信管1121班学号:姓名:指导老师:题目:计算器要求:利用栈原理,设计一个可以计算所输入表达式的程序,要求可以计算正数,负数,小数的加减乘除运算和括号运算功能:对输入的式子进行判断式子格式是否正确,然后进行运算,并输出最终结果分析:该问题的实现需用到两个栈,一个栈用于把中缀表达式转化成后缀表达式(见图1):这个栈从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,若是左括号则直接进栈,右括号这把左括号之前的栈顶符号都出栈,并最后把左括号也出栈,碰到多个括号嵌套的也一样,只要匹配括号即可,一直到最终输出后缀表达式为止。
一个栈用于计算后缀表达式(见图2):这个栈则用于储存数字,从左到右把碰到符号之前的数字都进栈,当碰到运算符时则从栈顶弹出两个元素,并同该运算符进行运算,并把结果进栈,直到最后没有表达式遍历完为止。
图1:例如中缀表达式“9+(3-1)*3+10/2”转化为后缀表达式“9 3 1-3*+ 10 2/+”第一个是:9输出第二个是:+ 进栈第三个是:3输出第四个是:(进栈ToptopTop第五个是:-进栈(略) 第六个是: )把(和他上面的运算符都出栈 其他的以此类推图二:9 3 1-3*+ 10 2/+把9 3 1都入栈 遇到 -- 弹出两个栈顶元素(1和3)并相减,再把结果入栈 (其他省略)定义了一个栈top TopTop其中:void Push(DataType x); //入栈void Pop(); //进栈DataType GetTop(); //取栈顶元素int isEmpty(); //判断栈是否为空int prior(char fuhao); //计算符号的优先级float calculate(string arr,int n); //计算算式结果int judge(string mode); //判断算式是否含有非法字符代码:#include<iostream>#include<string>using namespace std;const int StackSize=128;int prior(char fuhao); //计算符号的优先级float calculate(string arr,int n); //计算算式结果int judge(string mode); //判断算式是否含有非法字符template<class DataType>class Stack{public:Stack(){top=-1;}~Stack(){};void Push(DataType x); //入栈void Pop(); //进栈DataType GetTop(); //取栈顶元素int isEmpty(); //判断栈是否为空private:int top;DataType data[StackSize];};template<class DataType>void Stack<DataType>::Push(DataType x){if(top==StackSize-1)throw "上溢";top++;data[top]=x;}template<class DataType>void Stack<DataType>::Pop(){if(top==-1)throw "下溢";data[top--];}template<class DataType>DataType Stack<DataType>::GetTop(){if(top!=-1)return data[top];throw "空栈";}template<class DataType>int Stack<DataType>::isEmpty(){if(top==-1)return 1;elsereturn 0;}int prior(char fuhao) //计算符号的优先级,设+和-为1,*和/为2 {if(fuhao=='+'||fuhao=='-')return 1;if(fuhao=='*'||fuhao=='/')return 2;return 0;}int judge(string mode) //判断算式是否含有非法字符{string temp="";if(((mode.at(0)<'0' || mode.at(0)>'9') && mode.at(0)!='_') ||//算式的开头为非数字和负号((mode.at(mode.length()-1)<'0' || mode.at(mode.length()-1)>'9') && mode.at(mode.length()-1)!=')')) //算式结尾不是数字和)return 1;for(int i=0;i<mode.length();i++){if((mode.at(i)<'0' || mode.at(i)>'9') && mode.at(i)!='.' &&mode.at(i)!='+'&& mode.at(i)!='-'&& mode.at(i)!='*'&& mode.at(i)!='/'&& mode.at(i)!='(' && mode.at(i)!=')' && mode.at(i)!='_')//算式含有除了0-9,+-*/,(),. 和_ 之外的字符return 1;if((mode.at(i)>='0' && mode.at(i)<='9') || mode.at(i)=='.' || mode.at(i)=='_') //把算式所有数字和. _ 置为0{temp+="0";if(i>=1 && mode.at(i-1)==')') //右括号不是和运算符想连,返回错误return 1;}else if(mode.at(i)=='+' || mode.at(i)=='-' || mode.at(i)=='*' || mode.at(i)=='/') //把算式的+-* /置为1temp+="1";else if(mode.at(i)=='(' || mode.at(i)==')') //把算式的()置为2{temp+="2";if(mode.at(i)=='(' && temp.at(i-1)=='0') //左括号直接和数字想连,返回错误return 1;}if(i>=1){if(temp.at(i)==1 && temp.at(i)==temp.at(i-1)) //如果有连续的运算符,返回错误return 1;}}return 0; //返回算式格式正确}float calculate(string arr[],int n){Stack<float>S;int i=0,k=0;float f1,f2; //f1,f2表示栈顶的两个元素for(i=0;i<n;i++){if(arr[i]!="+" && arr[i]!="-" && arr[i]!="*" && arr[i]!="/"){S.Push(atof(arr[i].c_str())); //把所有的数字转化成float类型入栈}else{if(arr[i]=="+") //把+号之前的两个元素出栈并相加{f1=S.GetTop();S.Pop();f2=S.GetTop();S.Pop();S.Push(f2+f1);}else if(arr[i]=="-") //把-号之前的两个元素出栈并相减{f1=S.GetTop();S.Pop();f2=S.GetTop();S.Pop();S.Push(f2-f1);}else if(arr[i]=="*") //把*号之前的两个元素出栈并相乘{f1=S.GetTop();S.Pop();f2=S.GetTop();S.Pop();S.Push(f2*f1);}else if(arr[i]=="/") //把/号之前的两个元素出栈并相除{f1=S.GetTop();S.Pop();f2=S.GetTop();S.Pop();S.Push(f2/f1);}}}return S.GetTop(); //返回最后的结果}void main(){Stack<char> S1;string mode; //输入的算式string shuzi=""; //储存数字char fuhao; //储存符号int i=0,j=0,flag=1; //i循环统计算式的长度,j统计后缀表达式对象的个数,flag为判断是否继续输入的标志string arr[50]; //储存转化后的后缀表达式字符串数组while(flag) //判断是否继续输入{cout<<"★★★★★★★★★★计算器★★★★★★★★★★"<<endl<<endl;cout<<"请注意:只能输入数字,加减乘除和符号,其中负号为_ "<<endl;cout<<"请输入式子:";cin>>mode;if(judge(mode)) //判断输入算式是否正确{cout<<"算式不正确,请重新输入!"<<endl;system("pause");system("cls");continue;}else{for(i=0;i<mode.length();i++){while(i<mode.length() && ((mode.at(i)>='0' &&mode.at(i)<='9') || mode.at(i)=='.' || mode.at(i)=='_')) //提取数字{if(mode.at(i)=='_') //"_"代表符号{shuzi="-";i++;}shuzi+=mode.at(i);i++;}if(!shuzi.empty()){arr[j]=shuzi;j++;shuzi="";}if(i<mode.length()) //符号利用堆栈中缀转成后缀{fuhao=mode.at(i);if(fuhao=='(') //遇到”(“就入栈{S1.Push('(');}else{if(fuhao==')') //遇到”)“就把”(“之前的符号都出栈{while(S1.GetTop()!='('){arr[j]=S1.GetTop();S1.Pop();j++;}S1.Pop(); //把”(“出栈}else{if(S1.isEmpty()) //空栈就入栈{S1.Push(fuhao);}else{if(prior(fuhao)>prior(S1.GetTop()))//当前符号优先级比栈顶符号高,入栈{S1.Push(fuhao);}else{while(!S1.isEmpty() &&(prior(fuhao)<=prior(S1.GetTop()))) //当前符号优先级比栈顶符号低,把栈顶优先级较低的都出栈,再把当前符号入栈{arr[j]=S1.GetTop();S1.Pop();j++;}S1.Push(fuhao);}}}}}}while(!S1.isEmpty()) //把剩下的符号都输出{arr[j]=S1.GetTop();S1.Pop();j++;}cout<<"结果为:"<<calculate(arr,j)<<endl; //通过calculate(arr,j)获取结果cout<<"*************************************** "<<endl;cout<<" * 是否继续?* "<<endl;cout<<" * 1、是* "<<endl;cout<<" * 0、否* "<<endl;cout<<"*************************************** "<<endl<<endl;cin>>flag; //输入1继续,输入0结束system("cls");}}}收获和体会:通过本次课程设计,使我对数据结构的了解进一步加深,在编写过程中遇到了一些问题,通过思考,或者网上找资料,使我的知识面进一步加深,从网上也学习了一些原先课本里没有介绍到的内容。
栈实现计算器
栈实现计算器
1. 使⽤栈完成表达式得计算思路, 通过⼀个index值(索引),来遍历我们的表达式
2.发现是⼀个数字,直接⼊数栈
3.如果发现扫描到是⼀个符号,就分如下情况
3.1 如果发现当前符号栈为空,直接⼊栈
3.2 如果符号栈有操作符,就进⾏⽐较,如果当前得操作符的优先级⼩于或者等于栈中的操作符,需要从数栈中pop两个数,(if 当前<=你)
再从符号栈中pop出⼀个符号,进⾏运算,将得到的结果,⼊数栈,然后将当前的操作符⼊符号栈
3.3 如果当前的操作符的优先级⼤于栈中的操作符就直接⼊符号栈
4. 当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运⾏
5. 最后再数栈只有⼀个数字,就是表达式的结果
3就是⼊数栈, 加号直接⼊符号栈 ,2 直接⼊数栈,乘号来的时候进⾏判断,6也直接⼊栈, 减号满⾜优先级⼩于栈中操作符
判断完之后数字的2和6 pop 出栈,符号栈* pop出栈然后进⾏运算, 得到结果12 push⼊数栈, 然后减法也push⼊符号栈, 最后2 ⼊栈扫描完毕后依次进⾏运算, 减法是后⾯弹出来的数据 - 前⾯弹出来的数据依次pop出两个数字和⼀个运算符
12 -2 结果10 有push ⼊栈 ,然后指针上移, 最后出栈10和3 ,加号结果就是13
栈中最后⼀个数字就是结果,从下往上访问,访问不到10。
栈的应用1——超级计算器(中缀与后缀表达式)C语言
栈的应⽤1——超级计算器(中缀与后缀表达式)C语⾔这⾥要学的程序主要⽤来实现⼀个功能——输⼊表达式输出结果,也就是⼀个计算器。
效果如下:这个程序主要有两个步骤:1、把中缀表达式转换为后缀表达式;2、计算后缀表达式的结果。
⾸先先明⽩⼏个问题:1、为什么要转换为后缀表达式?因为后缀表达式容易实现计算机计算结果。
(可以百度⼀下后缀表达式,⼜称逆波兰式)2、怎么把中缀表达式转换为后缀表达式?3、怎么⽤后缀表达式输出结果?相信如果弄明⽩了上⾯⼏个问题,有C语⾔基础的同学就可以编出这个程序啦。
⽽后⾯两个问题都要⽤到⼀个数据结构——栈。
实际上数据结构只是⼀种思想,⼀种思维,是连接⼈脑与计算机的桥梁(纯属个⼈杜撰= =) 好,那么我们先学怎么把中缀表达式转换为后缀表达式。
为了简化问题,我们不妨设输⼊的数字都是⼀位整数,这样读⼊的时候只需要以字符的⽅式逐个读⼊即可,也就是说读⼊的必定是数字或者+-*/,读到回车视为结束;另外不妨直接将结果打印到屏幕上,也就是说结果不必存储(这样我们可以更多地关注算法本⾝,⽽⾮输⼊输出⽅式的细枝末节) 类似上⾯的图⽚,它的后缀表达式是 9 3 1 - 2 * + 5 2 / + 怎么得到的呢?下⾯开始讲这个转换的算法: 1、设置⼀个栈,栈底填⼀个"@"作为结束符(当然也可以⽤别的符号,⾄于为什么要⽤⼀会讲优先级的时候会说); 2、开始逐个字符读⼊; 3、如果读⼊的是数字,直接打印printf("%c ",c);(数字后⾯打印⼀个空格作为间隔符,要不然没法看了931-。
不解释) 4、如果读⼊的是"("直接进栈; 5、如果读⼊的是")",说明前⾯肯定读⼊过⼀个"("找到这个左括号,把两者之间的符号逐个弹栈(这⾥要说明的是,括号不必打印,因为后缀表达式没有括号); 6、如果不是上⾯的⼏种情况,那必定是+-*/中的⼀个啦,这样来说就容易多了。
[Python实战]使用栈实现简易计算器
我们这次实现的命令行计算器,支持加减乘除、括号、浮点数、负数,以及查看历史和退出功能。
主要的思路:read - parse - print - loop。
read 阶段是指读取用户在提示符(cal> )之后输入的字符串。
parse 阶段包括:将用户输入的字符串分割成单个对象比如:符号 +,或者数字 1.2 。
其次将中缀表达式转化后缀表达式,接下来计算后缀表达式的数值。
print 阶段指的是将 parse 阶段的数值打印在终端上。
loop 阶段是指重复上述操作,除非用户输入 exit 符号或者 Ctrl + C 终止程序运行。
实现效果图:栈为了实现后面的中缀、后缀表达式,我们需要借助栈这种数据结构。
栈是一种先进后出的数据结构,函数调用时就会使用栈来保存当前程序的地址及其他信息。
下面简单说明栈的使用:push 函数在栈的顶部添加元素,pop 函数删除栈顶的元素,top 函数查看栈顶元素。
class Stack:def push(self, value: T) -> None: passdef pop(self) -> T: passdef top(self) -> T: pass分词分词是 parse 阶段的重要部分。
我们定义符号 + - * / ( )。
将这些字符串中的这些符号替换为:空格 + 符号 + 空格+ => 空格+空格将字符串按空格分割,得到最终的分词经过上述操作,就可以实现对正数以及操作符的分词功能。
def tokenize(expression: str) -> Generator[str, None, None]:for symbol in symbols:# 替换字符串expression = expression.replace(symbol, f" {symbol} ") # 分割字符串 seq: List[str] = expression.spli t()为了实现对负数的分词,我们需要迭代分词序列,将‘-’ 与后面的数字转换成一个整体。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
栈的应用:C实现简单计算器(表达式的计算)
作为栈的著名应用,表达式的计算可以用下面方法实现:
首先建立两个栈,操作数栈NUM_S和运算符栈OPR_S。
其中,操作数栈用来存储表达式中的操作数;运算符栈用来存储表达式中的运算符。
可以用字符‘=’来表示表达式结束符。
自左至右的扫描待处理的表达式,并假设当前扫描到的符号为W,根据不同的符号W 做如下不同的处理:
1.若W为操作数,则将W压入操作数栈NUM_S,且继续扫描下一个字符;
2.若W为运算符,则根据运算符的性质做相应的处理:
(0)若符号栈为空,无条件入栈当前指针指向的字符
(1)若w为不大于运算符栈栈顶的运算符,则从操作数栈NUM_S中弹出两个操作数,设先后弹出的操作数为a、b,再从运算符栈
OPR_S中弹出一个运算符,比如为+,然后作运算a+b,并将运算结果压入操作数栈NUM_S。
(2)若w为左括号或者运算符的优先级大于运算符栈栈顶的运算符,则将运算符W 压入运算符栈OPR_S,并继续扫描下一个字符。
(3)若运算符W为右括号,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为+,然后作运
算a+b, 并将运算结果压入操作数栈NUM_S),直到从运算符栈中弹出第一个左括号。
(4)若运算符W为表达式结束符‘=’,循环操作(设先后弹出的操作数为a、b,再从运算符栈OPR_S中弹出一个运算符,比如为
+,然后作运算a+b, 并将运算结果压入操作数栈NUM_S),直到运算符栈为空为止。
此时,操作数栈栈顶元素即为表达式的
值。
====================================================================== ===
举例:计算3+(5-2*3)/4-2=
(1)开始栈为空,3入栈,+入栈,(无条件入栈,5入栈,-号优先级比(高,所以-号入栈,2入栈,*优先级比目前栈顶的-号优先级高,所以*入栈,3入栈,接着扫描到)括号,)括号不入栈
| | | |
--------- ----------
| 3 | | * |
--------- ----------
| 2 | | - |
--------- ----------
| 5 | | ( |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(2)在)括号碰到(括号之前,让操作数栈一直出栈,直到让左括号出栈为止所以:2,3弹出操作数栈,*弹出操作符号栈,计算2*3 = 6,然后将6入操作数栈
| | | |
--------- ----------
| | | |
--------- ----------
| 6 | | - |
--------- ----------
| 5 | | ( |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(3)接着6,5弹出操作数栈,-弹出操作符栈,计算5-6 = -1,然后将-1入操作数栈,然后左括号出栈
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| -1 | | |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(4)接着向下遍历表达式,到/号,优先级比操作符栈栈顶+高,所以/压栈,然后接着扫描,4入栈,再接着扫描到-号,优先级比操作符栈栈顶/的优先级低,则操作数栈4,-1出栈,操作符栈/出栈,计算-1/4 = 0,
| | | |
--------- ----------
| | | |
--------- ----------
| 4 | | |
--------- ----------
| -1 | | / |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(5)将上一步结果0压入操作数栈,刚才扫描到的-号,优先级和+号相同,则-号不入栈,将0,3弹出,将+号弹出,
计算3+0 = 3
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 0 | | |
--------- ----------
| 3 | | + |
--------- ----------
操作数栈操作符栈
(6)将上一步中的结果3压入操作数栈,-号入操作符栈,接着扫描到2,2入操作数栈,接着扫描,发现到了=号,则操作数栈2,3弹出,操作符栈-号弹出,计算3-2 = 1
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 2 | | |
--------- ----------
| 3 | | - |
--------- ----------
操作数栈操作符栈
(7)将上一步中的结果1压入操作数栈,最后1弹出栈,作为最后结果。
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| | | |
--------- ----------
| 1 | | |
--------- ----------
操作数栈操作符栈
//=========================== 完
==================================//。