通过把“中缀转后缀”和“后缀求值”两个算法功能集成在一起(非简单的顺序调用),
实现对中缀表达式直接求值,新算法是直接扫描后缀表达式
(支持 + - * / ^ 五种运算)
输入格式:
共1行,为1个字符串,即一个中缀表达式,
其中每个数字或符号间由一个空格隔开。
输出格式:
共1行,为一个整数,即求值的结果。
输入样例:
( 2 + 3 ) * 6 + 4 / 2
输出样例:
2 3+6*4 2/+
32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define maxsize 50
typedef struct
{
float data[maxsize];
int top;
}opstack;
typedef struct
{
char data[maxsize];
int top;
}stack;
void InitStack(stack *s);
int GetTop(stack s, char *e);
void Pop(stack *s, char *e);
void Push(stack *s, char e);
void TranslateExpress(char s1[], char s2[]);
float ComputeExpress(char s[]);
int StackEmpty(stack s);
int main()
{
char a[maxsize],b[maxsize];
float f;
printf("请输入一个算术表达式:");
gets(a);
printf("中缀表达式为: %s\n",a);
TranslateExpress(a,b);
printf("后缀表达式为: %s\n",b);
f=ComputeExpress(b);
printf("计算结果为: %f\n",f);
return 0;
}
void InitStack(stack *s)
{
s->top=0;
}
int GetTop(stack s, char *e)
{
if(s.top<=0) return 0;
else
{
*e=s.data[s.top-1];
return 1;
}
}
void Pop(stack *s, char *e)
{
if(s->top<=0) printf("栈空!");
else *e=s->data[--s->top];
}
void Push(stack *s, char e)
{
if(s->top>=maxsize) printf("栈满!");
else s->data[s->top++]=e;
}
int StackEmpty(stack s)
{
if(s.top==0) return 1;
else return 0;
}
float ComputeExpress(char a[])
{
opstack s;
int i=0, value;
float x1, x2, result;
s.top=-1;
while (a[i]!='\0')
{
if(a[i]!=' '&&a[i]>='0'&&a[i]<='9')
{
value=0;
while (a[i]!=' ')
{
value=10*value+a[i]-'0';
i++;
}
s.top++;
s.data[s.top]=value;
}
else
{
switch(a[i])
{
case '+':
x1=s.data[s.top--];
x2=s.data[s.top--];
result=x1+x2;
s.data[++s.top]=result;
break;
case '-':
x1=s.data[s.top--];
x2=s.data[s.top--];
result=x2-x1;
s.data[++s.top]=result;
break;
case '*':
x1=s.data[s.top--];
x2=s.data[s.top--];
result=x1*x2;
s.data[++s.top]=result;
break;
case '/':
x1=s.data[s.top--];
x2=s.data[s.top--];
result=x2/x1;
s.data[++s.top]=result;
break;
case '^':
x1=s.data[s.top--];
x2=s.data[s.top--];
result=pow(x2,x1);
s.data[++s.top]=result;
break;
}
i++;
}
}
if(!s.top!=-1)
{
result=s.data[s.top];
s.top--;
if(s.top==-1) return result;
else
{
printf("表达式错误!");
exit(-1);
}
}
}
void TranslateExpress(char str[], char exp[])
{
stack s;
char ch, e;
int i=0, j=0;
InitStack(&s);
ch=str[i++];
while(ch!='\0')
{
switch(ch)
{
case '(':
Push(&s,ch);
break;
case ')':
while (GetTop(s,&e)&&e!='(')
{
Pop(&s,&e);
exp[j++]=e;
}
Pop(&s,&e);
break;
case '+':
case '-':
while (!StackEmpty(s)&&GetTop(s,&e)&&e!='(')
{
Pop(&s,&e);
exp[j++]=e;
}
Push(&s,ch);
break;
case '*':
case '/':
while(!StackEmpty(s)&&GetTop(s,&e)&&e=='/'||e=='*'||e=='^')
{
Pop(&s,&e);
exp[j++]=e;
}
Push(&s,ch);
break;
case '^':
while(!StackEmpty(s)&&GetTop(s,&e)&&e=='^')
{
Pop(&s,&e);
exp[j++]=e;
}
Push(&s,ch);
break;
case ' ':
break;
default:
while(ch>='0'&&ch<='9')
{
exp[j++]=ch;
ch=str[i++];
}
i--;
exp[j++]=' ';
}
ch=str[i++];
}
while(!StackEmpty(s))
{
Pop(&s,&e);
exp[j++]=e;
}
exp[j]='\0';
}