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

如题所述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define error 0
#define ok 1
#define overflow -1
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define OPSETSIZE 7
char OPSET[OPSETSIZE]={'+','-','*','/','(',')','#'};
unsigned char Prior[7][7] = { // 算符间的优先关系
'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',' ',
'>','>','>','>',' ','>','>',
'<','<','<','<','<',' ','='
};
typedef int Status;

template <typename T>
struct SqStack
{
T *top;
T *base;
int stacksize;

};//顺序栈结构模板

template <typename T1,typename T2>
Status InitStack(T1 &S)
{
S.base=(T2 *)malloc(STACK_INIT_SIZE*sizeof(T2));
if(!S.base) exit (overflow);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return ok;
}//初始化栈函数模板

template <typename T1,typename T2>
Status Push(T1 &S,T2 e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(T2 *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(T2));
if(!S.base) exit (overflow);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return ok;
}//入栈函数模板

template <typename T1,typename T2>
Status Pop(T1 &S,T2 &e)
{
if(S.top==S.base) return error;
e=*--S.top;
return ok;
}//出栈函数模板

template <typename T1,typename T2>
T2 GetTop(T1 S)
{
if(S.top==S.base)
return error;
else
return *(S.top-1);

}//获取栈顶元素模板

Status In(char Test,char* TestOp) {
bool Find=false;
for (int i=0; i< OPSETSIZE; i++) {
if (Test == TestOp[i]) Find= true;
}
return Find;
}//判断是否为运算符

float Operate(float a,unsigned char theta, float b) {
switch(theta) {
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
default : return 0;
}
}//运算

int ReturnOpOrd(char op,char* TestOp) {
int i;
for(i=0; i< OPSETSIZE; i++) {
if (op == TestOp[i]) return i;
}
return 0;
}

char precede(char Aop, char Bop) {
return Prior[ReturnOpOrd(Aop,OPSET)][ReturnOpOrd(Bop,OPSET)];
}//ReturnOpOrd和precede组合,判断运算符优先级

float EvaluateExpression() {
// 算术表达式求值的算符优先算法。
// 设OPTR和OPND分别为运算符栈和运算数栈,OPSET为运算符集合。
SqStack<char> OPTR; // 运算符栈,字符元素
SqStack<float> OPND; // 运算数栈,实数元素
char TempData[20];
float Data,a,b;
char theta,c,x,Dr[2];

InitStack<SqStack<char>,char> (OPTR);
Push (OPTR, '#');
InitStack <SqStack<float>,float>(OPND);
strcpy(TempData,"\0");//将TempData置为空
c=getchar();
while (c!= '#' || GetTop<SqStack<char>,char>(OPTR)!= '#')
{
if (!In(c, OPSET))
{
Dr[0]=c;
Dr[1]='\0';//存放单个数
strcat(TempData,Dr);//将单个数连到TempData中,形成字符串
c=getchar();
if(In(c,OPSET))//如果遇到运算符,则将字符串TempData转换成实数,入栈,
并重新置空
{
Data=(float)atof(TempData);
Push(OPND, Data);
strcpy(TempData,"\0");
}
}
else
{ // 不是运算符则进栈
switch (precede(GetTop<SqStack<char>,char>(OPTR), c)) {
case '<': // 栈顶元素优先权低
Push(OPTR, c);
c=getchar();
break;
case '=': // 脱括号并接收下一字符
Pop(OPTR, x);
c=getchar();
break;
case '>': // 退栈并将运算结果入栈
Pop(OPTR, theta);
Pop(OPND, b);
Pop(OPND, a);
Push(OPND, Operate(a, theta, b));
break;
} // switch
}
} // while
return GetTop<SqStack<float>,float>(OPND);
} // EvaluateExpression

void main()
{
printf("请输入表达式(end #):\n");
printf("%f\n",EvaluateExpression());
}

给你一个完全的程序,本人自己写的。
温馨提示:内容为网友见解,仅供参考
无其他回答

数据结构:利用栈来实现算术表达式求值的算法。
};\/\/顺序栈结构模板 template <typename T1,typename T2> Status InitStack(T1 &S){ S.base=(T2 *)malloc(STACK_INIT_SIZE*sizeof(T2));if(!S.base) exit (overflow);S.top=S.base;S.stacksize=STACK_INIT_SIZE;return ok;}\/\/初始化栈函数模板 template <typename T1,typename T2> Sta...

java实现算术表达式求值
需要根据配置的表达式(例如:5+12*(3+5)\/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类。后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后缀表达式为32+,3*(2+1)的后缀表达式为:321+*,解决表达式求值首先需要根据字符串表达式求出后缀表达式,然后...

(二)用顺序栈实现算术后缀表达式求值
1、算法思想后缀表达式求值步骤:a、循环读出后缀表达式中的每一个字符;b、若是数字,将对应的字符串转换成整数,入栈;c、若是运算符,从栈中弹出2个数,将运算结果再压入栈;d、若... 1、算法思想后缀表达式求值步骤:a、循环读出后缀表达式中的每一个字符;b、若是数字,将对应的字符串转换成整数,入栈;c、若是...

基于栈的中缀算术表达式求值
基于栈的中缀算术表达式求值是一个常见的算法问题。中缀表达式是一种常见的数学表达式表示方法,例如3+4*2\/(1-5)。在这个问题中,我们需要使用栈来求解表达式的值。我们需要了解中缀表达式的语法规则。中缀表达式由操作数(数字、字母等)和运算符(加、减、乘、除等)组成。运算符的优先级由括号和数...

栈的应用expr(表达式求值)!给定一个只包含加法和乘法的算术表达式,请你...
利用乘法先运算的性质,把压入栈的乘法先运算最后再算加法就好了:include <iostream>#include <sstream>#include <stack>using namespace std;const int MaxLen = 4096;char expr[MaxLen];int main(){stack<int> num;cin.getline(expr, MaxLen);stringstream e(expr);int n;char o;e >> n;...

利用数据结构中的栈实现表达式求值 例如4+2*(10-3)-10\/5 先只考虑整 ...
S){ \/\/返回S的栈顶元素 return *(S.top-1);} void PushChar(StackChar &S,char e){ S.top++=e;} void PushFloat(StackFloat &S,float e){ S.top++=e;} void PopChar(StackChar &S,char &e){ e=*--S.top;} void PopFloat(StackFloat &S,float &e){ e=*--S.top;...

栈的应用举例:数制转换,表达式求值
关于表达式的分析与求值是计算机软件专业中“编译原理”课程极其重要的部分,主要用于最初的词法分析。其表示方式有:前缀、中缀、后缀表示法。其数据结构可以使用一个堆栈来表示。具体的实现代码,我以前使用的书籍是《C语言大全》,那上面就有完整的、现成的代码,可以供你参考运行。同时你还可以参考《编译...

栈的实现及算法应用
实现栈时,可以使用数组或链表。使用链表作为栈结构时,链表头部作为栈顶更为方便。在JavaScript中,可以通过定义一个Stack类,包含数据存储和栈顶元素指向的属性,以及常用操作方法(如push、pop和peek)来实现栈。在表达式求值中,栈是不可或缺的工具。例如,逆波兰表达式求值通过使用栈来简化操作,避免了...

ACM——表达式求值教程
遇到括号时,遇到 "(" 压入,遇到 ")" 时,弹出栈直到遇到匹配的 "("。尽管这个基础方法可以处理大部分情况,但具体实现可能需要根据题目要求进行调整。例如,某些题目可能要求支持负数运算,这就需要在处理数字时特别处理。总之,理解并灵活运用栈的特性,能够帮助我们高效地解决这类表达式求值问题。

中缀表达式转后缀表达式并求值(C++链式栈实现)
实现后缀表达式求值函数。该函数同样利用栈,当遇到操作数时直接压栈;遇到运算符时,弹出栈顶两个操作数,进行运算后将结果压栈。循环进行直至表达式结束。通过这种方式,可以有效处理多位整数及负数的中缀表达式运算。使用类模板可以增加代码的复用性。最终,通过链式栈实现了中缀到后缀的转换与后缀表达式的...

相似回答
大家正在搜