逆波兰表达式就是所谓的后缀表达式,运算符号都在运算变量的后面,这样计算机进行计算的时候是非常方便和快捷的。将中缀表达式转换成后缀表达式的算法如下图所示:
根据上图可以直接出来代码,另外转换为后缀表达式之后,对逆波兰表达式的计算就会很方便了,看下图:
需要注意的是,重点不在写程序,重点在于这些个图是怎么出来的,这些也都是前人的总结啊,示例代码如下:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//栈结构
typedef struct Stack
{
char *elem;
int top;
int size;
}Stack;
//初始化栈
void initStack(Stack *S)
{
S->elem=(char *)malloc(30*sizeof(char));
S->top=-1;
S->size=30;
}
//判断是否栈为空
int isEmpty(Stack *S)
{
if(S->top==-1)
return 1;
else
return 0;
}
//入栈
void push(Stack *S,char x)
{
if(S->top==S->size-1)
{
printf("Stack Overflow!\n");
return;
}
S->elem[++S->top]=x;
}
//出栈
char pop(Stack *S)
{
char x;
if(S->top==-1)
{
printf("Stack Empty!\n");
return 0;
}
x=S->elem[S->top--];
return x;
}
//取栈顶元素,但是不删除栈顶元素
char top(Stack *S)
{
char x;
if(S->top==-1)
{
printf("Stack Empty!\n");
return 0;
}
x=S->elem[S->top];
return x;
}
//判断当前运算符和栈顶的元素的优先级大小
int isBigger(char cur, char top)
{
if((cur=='*' || cur=='/') && (top=='+' || top=='-'))
return 1;
else if(top=='(')
return 1;
else
return 0;
}
//计算逆波兰表达式的值
void cal(char *buffer)
{
int stack[30];
int top=-1;
unsigned int i=0;
int j=0;
int a,b;
char * temp=(char *)malloc(10*sizeof(char));//存放运算分量的临时数组
memset(temp,0,10);
for(i;i<strlen(buffer);i++)
{
if(buffer[i]>='0' && buffer[i]<='9')
temp[j++]=buffer[i];
else if(buffer[i]=='&')
{
stack[++top]=atoi(temp);
j=0;
memset(temp,0,10);
}
else if(buffer[i]=='+')
{
a=stack[top--];
b=stack[top--];
stack[++top]=a+b;
}
else if(buffer[i]=='-')
{
a=stack[top--];
b=stack[top--];
stack[++top]=b-a;
}
else if(buffer[i]=='*')
{
a=stack[top--];
b=stack[top--];
stack[++top]=a*b;
}
else if(buffer[i]=='/')
{
a=stack[top--];
b=stack[top--];
stack[++top]=b/a;
}
}
printf("%d\n",stack[top]);
}
int main()
{
char ch;
char buffer[30];
int t=0;
int i=0;
Stack s;
FILE * fp;
initStack(&s);
fp=freopen("in.txt","r",stdin);
while(scanf("%c",&ch))
{
if(ch=='#')//若字符串扫描完毕
{
while(!isEmpty(&s) && top(&s)!='(')
buffer[t++]=pop(&s);
if(isEmpty(&s))
{
buffer[t]='\0';
printf("%s\n",buffer);
cal(buffer);
break;
}
else if(top(&s)=='(')
{
printf("0 wrong...\n");
break;
}
}
if(ch=='+' || ch=='-' || ch=='*' || ch=='/')//运算符
{
//buffer[t++]='&';
while( !isEmpty(&s) && !isBigger(ch,top(&s)))//当前运算符比栈顶元素的优先级小,并且栈不为空
{
buffer[t++]=pop(&s);
}
push(&s,ch);//栈为空,或者是当前运算符比栈顶元素的优先级大,则直接入栈
}
else if(ch=='(')//左括号则直接进栈
{
push(&s,ch);
}
else if(ch==')')//右括号
{
while(!isEmpty(&s) && top(&s)!='(')//当栈顶元素不为'(',并且栈不为空,则退栈输出
{
buffer[t++]=pop(&s);
}
if(top(&s)=='(')//如果栈顶元素为'(',则进栈
pop(&s);
else if(isEmpty(&s))//若栈为空,则输入的表达式有错
{
printf("1 wrong...\n");
break;
}
}
else if(ch>='0' && ch<='9')//输入的是运算分量
{
while(ch>='0' && ch<='9')
{
buffer[t++]=ch;
ch=fgetc(fp);
}
buffer[t++]='&';
fseek(fp,-1,1);
}
}
return 0;
}