不考虑运行,仅仅修改编译错误,如下:
// Q715047.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define Stack_Size 50
typedef char StackElementType; //运算符
typedef double StackElementType_num; //运算数
typedef struct
{
StackElementType elem[Stack_Size];
int top;
}SeqStack; //运算符栈
typedef struct
{
StackElementType_num elem[Stack_Size];
int top;
}SeqStack_num; //运算数栈
StackElementType_num ExpEvaluation();
void InitStack(SeqStack *S);
void InitStack_num(SeqStack_num *S);
int Push(SeqStack *S,StackElementType x);
int Push_num(SeqStack_num *S,StackElementType_num x);
int Pop(SeqStack *S,StackElementType *x);
int Pop_num(SeqStack_num *S,StackElementType_num *x);
int GetTop(SeqStack *S,StackElementType *x);
int GetTop_num(SeqStack_num *S,StackElementType_num *x);
StackElementType Compare(StackElementType ch1,StackElementType ch2);
StackElementType_num Execute(StackElementType_num a,StackElementType op,StackElementType_num b);
int main()
{
printf("%lf",ExpEvaluation());
return(0);
}
StackElementType_num ExpEvaluation()
{
char exp[100];//用字符数组将运算表达式存起来
int i=0,count=0;
printf("Please input an expression (Ending with #:)");
exp[i]=getchar();
while(exp[i]!='#')
{
i++;count++;
exp[i]=getchar();
}
SeqStack OPTR;
SeqStack_num OVS;
StackElementType ch,op,x;
StackElementType_num a,b,v;
InitStack(&OPTR);
InitStack_num(&OVS);
Push(&OPTR,'#');
for(i=0;i<count;i++)
{
ch=exp[i];
while(ch!='#'||GetTop(&OPTR,&x)!='#')
{
if(ch>='0'&&ch<='9')//不是操作符,是操作数,进OVS栈
{
int temp;
temp=ch-'0';//先把当前操作数从字符变为数字
i++;
ch=exp[i];
while(ch>='0'&&ch<='9')//继续判断下一位是否为操作数
{
temp=temp*10+ch-'0';
i++;
ch=exp[i];
}
Push_num(&OVS,temp);//压栈
}
else
switch(Compare(ch,GetTop(&OPTR,&x)))
{
case '>':Push(&OPTR,ch);
i++;ch=exp[i];
case '=':Pop(&OPTR,&op);i++;ch=exp[i];break;//脱括号
case '<':Pop(&OPTR,&op);//形成运算
Pop_num(&OVS,&b);
Pop_num(&OVS,&a);
v=Execute(a,op,b);
Push_num(&OVS,v);
break;
}
}
}
GetTop_num(&OVS,&v);
return(v);
}
//初始化
void InitStack(SeqStack *S)
{
/*构造一个空栈S*/
S->top=-1;
}
void InitStack_num(SeqStack_num *S)
{
/*构造一个空栈S*/
S->top=-1;
}
//进栈
int Push(SeqStack *S,StackElementType x)
{
if(S->top==Stack_Size-1)
return(FALSE);
S->top++;
S->elem[S->top]=x;
return(TRUE);
}
int Push_num(SeqStack_num *S,StackElementType_num x)
{
if(S->top==Stack_Size-1)
return(FALSE);
S->top++;
S->elem[S->top]=x;
return(TRUE);
}
//出栈
int Pop(SeqStack *S,StackElementType *x)
{
if(S->top==-1)
return(FALSE);
*x=S->elem[S->top];
S->top--;
return(TRUE);
}
int Pop_num(SeqStack_num *S,StackElementType_num *x)
{
if(S->top==-1)
return(FALSE);
*x=S->elem[S->top];
S->top--;
return(TRUE);
}
//读栈顶
int GetTop(SeqStack *S,StackElementType *x)
{
if(S->top==-1)
return(FALSE);
else
{
*x=S->elem[S->top];
return(TRUE);
}
}
int GetTop_num(SeqStack_num *S,StackElementType_num *x)
{
if(S->top==-1)
return(FALSE);
else
{
*x=S->elem[S->top];
return(TRUE);
}
}
//比较优先级,返回'>','<','='
StackElementType Compare(StackElementType ch1,StackElementType ch2)
//ch1为还未进栈的运算符,ch2为当前运算符栈顶元素
{
//'('未入栈时,优先级最高,入栈后,优先级最低
int m,n;
switch(ch1)
{
case '(':m=6;break;
case '*':
case '/':m=5;break;
case '+':
case '-':m=4;break;
case ')':m=3;break;
}
switch(ch2)
{
case '*':
case '/':n=6;break;
case '+':
case '-':n=5;break;
case ')':n=4;break;
case '(':n=3;break;
}
if(ch1>ch2)
return('>');
else if(ch1=ch2)
return('=');
else
return('<');
}
StackElementType_num Execute(StackElementType_num a,StackElementType op,StackElementType_num b)
{
StackElementType_num v = 0.0;
switch(op)
{
case '+':v=a+b;break;
case '-':v=a-b;break;
case '*':v=a*b;break;
case '/':v=a/b;break;
}
return(v);
}
但是你StackElementType_num ExpEvaluation()会死循环,原因是你在while循环里面i++,这会导致i超过输入长度范围,而没有办法退出循环
整个这段代码都要重写。
我这里有个写好的,你自己看下吧
// Q703345.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <stack> //use STL
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int MAXSIZE=256;
int InfixToPostfix(char *infix,char *postfix);
double Calculate(char *arr);
int main() {
cout << "请输入表达式:"; // prints 四则运算
char in[MAXSIZE]={0};
char postfix[MAXSIZE]={'\0'};
fgets(in,MAXSIZE,stdin);
if(InfixToPostfix(in,postfix)!=1)
{ cout<<"错误";
return -1;
}
//puts(in);
puts(postfix);
cout<<"由后缀表达式计算出的结果是" << Calculate(postfix) << endl;
return 0;
}
/*
将中缀表达式转换为后缀表达式
参数:infix 指向中缀表达式,以回车键即\n结尾。
postfix 指向后缀表达式临时缓冲区,用来存放转换后的结果。
附转换规则:从左到右遍历中缀表达式的每个数字和符号,若是数字则直接保存在postfix数组中;若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级不大于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或者栈空时,才将刚才的那个符号入栈。
*/
int InfixToPostfix(char *infix,char *postfix)
{
stack<char> s;
char c,e;
int j=0,i=0;
c=*(infix+i); //取出中缀表达式中的第一个字符
i++;
while('\n'!=c) //遇到换行符,表示转换结束
{
while(c>='0'&&c<='9') //先判断一下取出的字符是否是数字,如果是数字的话,则直接存入postfix数组
{
postfix[j++]=c;
c=*(infix+i);
i++;
if(c<'0'||c>'9') //如果不是数字,则在后面添加空格,以便区分各个符号
{
postfix[j++]=' ';
}
}
if(')'==c) //不是数字,则判断是否为右括号。[括号的优先级最高,所以,如果是右括号的话,就得先进行括号里的各种运算]
{
e=s.top();s.pop();
while('('!=e) //直到遇到左括号为止
{
postfix[j++]=e;
postfix[j++]=' ';
e=s.top();s.pop();
}
}
else if('+'==c||'-'==c) //如果是加减号,因为他俩的优先级最低了,所以此时先将栈里的所有符号出栈后(除非遇到左括号),再把此符号入栈
{
if(!(s.size())) //如果是空栈,则直接将加减号入栈
{
s.push(c);
}
else//如果不是空栈,首先将所有优先级大于加减的出栈,然后再把加减号入栈
{
do{
e=s.top();s.pop();
if('('==e)
{
s.push(e);
}
else
{
postfix[j++]=e;
postfix[j++]=' ';
}
}while(s.size()&&'('!=e); //将栈里的所有符号出栈(除非遇到左括号)
s.push(c); //最后将新来的加减号再入栈
}
}
else if('*'==c||'/'==c||'('==c) //如果是乘除号或左括号,因为他们的优先级高,所以直接入栈。
{
s.push(c);
}
else if('\n'==c) //判断一下,所有符号是否都已转换完成
{
break;
}
else //能走到这个else的,都是我不认识的符号了
{
// printf("\nError:input error,the character %d cann't recognize!\n",c);
return -1;
}
c=*(infix+i); //取出下一个字符进行转换
i++;
}
while(s.size()) //转换完成后,栈里可能还有没出栈的运算符号
{
e=s.top();s.pop();
postfix[j++]=e;
postfix[j++]=' ';
}
return true;
}
/*
计算后缀表达式的结果
参数:arr使用空格分隔的后缀表达式字符串。例:arr="31 5 + "
result 保存计算完毕后的结果
注:如何利用栈来计算后缀表达式的结果:依次取出后缀表达式中的符号进行比较,如果是数字,则直接入栈;如果是符号,则出栈两次,弹出两个要计算的因数,进行计算,之后再将计算结果入栈。知道后缀表达式中所有符号都已比较完毕。
*/
double Calculate(char *arr)
{
// printf("%s\n",arr);
double d,e,f; //d,e 存放两个因数。f存放d,e计算后的结果.
stack<double> s;
char *op; //存放后缀表达式中的每个因数或运算符
char *buf=arr; //声明bufhe saveptr两个变量,是strtok_r函数的需要。
char *saveptr=NULL;
while((op=strtok(buf," "))!=NULL) //利用strtok_r函数分隔字符串
{
buf=NULL;
switch(op[0])
{
case '+':
d=s.top();s.pop();
e=s.top();s.pop();
f=d+e;
s.push(f);
break;
case '-':
d=s.top();s.pop();
e=s.top();s.pop();
f=e-d;
s.push(f);
break;
case '*':
d=s.top();s.pop();
e=s.top();s.pop();
f=d*e;
s.push(f);
break;
case '/':
d=s.top();s.pop();
e=s.top();s.pop();
f=e/d;
s.push(f);
break;
default:
d=atof(op); //不是运算符,就肯定是因数了。所以,用atof函数,将字符串转换为double类型
s.push(d);
break;
}
}
double result=s.top();s.pop();
return result;
}