标签:style os io 使用 ar for sp on c
一个表达式E的逆波兰形式可以如下定义:
(1)如果E是一个变量或常量,则E的后缀式是E本身。
(2)如果E是E1 op E2形式的表达式,这里op是如何二元操作符,则E的后缀式为E1‘E2‘ op,这里E1‘和E2‘分别为E1和E2的后缀式。
(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。(括号直接剔除)
如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+
(a+b)*c-(a+b)/e的后缀表达式为:
(a+b)*c-(a+b)/e
→((a+b)*c)((a+b)/e)-
→((a+b)c*)((a+b)e/)-
→(ab+c*)(ab+e/)-
→ab+c*ab+e/-
(1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈
(2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。
(3)若取出的字符是“(”,则直接送入S1栈栈顶。
(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。
(5)重复上面的1~4步,直至处理完所有的输入字符
(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。
逆波兰的机器运算
下面以(a+b)*c为例子进行说明:
(a+b)*c的逆波兰式为ab+c*,假设计算机把ab+c*按从左到右的顺序压入栈中,并且按照遇到运算符就把栈顶两个元素出栈,执行运算,得到的结果再入栈的原则来进行处理,那么ab+c*的执行结果如下:
1)a入栈(0位置)
2)b入栈(1位置)
3)遇到运算符“+”,将a和b出栈,执行a+b的操作,得到结果d=a+b,再将d入栈(0位置)
4)c入栈(1位置)
5)遇到运算符“*”,将d和c出栈,执行d*c的操作,得到结果e,再将e入栈(0位置)
经过以上运算,计算机就可以得到(a+b)*c的运算结果e了。
#include"iostream.h"
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#define max 100
char ex[max]; /*存储后缀表达式,不需要用另一个栈,直接用数组。这样也方便机器读取*/
void trans()
{ /*将算术表达式转化为后缀表达式*/
char str[max]; /*存储原算术表达式*/
char stack[max]; /*作为栈使用*/
char ch;
int sum,i,j,t,top=0;
printf("*****************************************\n");
printf("*输入一个求值的表达式,以#结束。*\n");
printf("******************************************\n");
printf("算数表达式:");
i=0; /*获取用户输入的表达式*/
do
{
i++;
cin>>str[i];
}while(str[i]!=‘#‘ && i!=max);
sum=i;
t=1;i=1;
ch=str[i];i++;
//
while(ch!=‘#‘){
switch(ch)
{
case ‘(‘: /*判定为左括号*/
top++;stack[top]=ch; //stack从1开始
break;
case ‘)‘: /*判定为右括号*/
while(stack[top]!=‘(‘)
{ //把()之间的全部放到目标数组里面
ex[t]=stack[top];top--;t++;
}
top--; //除去(符号
break;
case ‘+‘: /*判定为加减号*/
case ‘-‘:
//(看做优先级最低,加减运算之比“(”优先级高。只有出现比它低的情况它才压入进去(或者运算栈为空),否则把栈内的都放到目标数组
while(top!=0&&stack[top]!=‘(‘)
{
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case ‘*‘: /*判定为乘除号*/
case ‘/‘:
//遇到和自己相同运算级的仍然需要把栈送入目标中。对于乘法除法,(,加减肯定比自己优先级小
while(stack[top]==‘*‘||stack[top]==‘/‘)
{
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case ‘ ‘:break;
default:
while(ch>=‘0‘&&ch<=‘9‘)
{ /*判定为数字*/
ex[t]=ch;t++;
ch=str[i];i++;
}
i--;
ex[t]=‘ ‘;t++;
//这里每个数字之间存在一个空格,这样保证被分解的时候,不至于把两个数当做一个数
}
ch=str[i];i++;
}
while(top!=0)
{
ex[t]=stack[top];t++;top--;
}
ex[t]=‘ ‘;
printf("\n\t原来表达式:");
for(j=1;j<sum;j++)
printf("%c",str[j]);
printf("\n\t逆波兰式:",ex);
for(j=1;j<t;j++)
printf("%c",ex[j]);
}
void compvalue(){ /*计算后缀表达式的值*/
float stack[max],d; /*作为栈使用*/
char ch;
int t=1,top=0; /*t为ex下标,top为stack下标*/
ch=ex[t];t++;
while(ch!=‘ ‘){
switch(ch){
case ‘+‘:
stack[top-1]=stack[top-1]+stack[top];
top--;
break;
case ‘-‘:
stack[top-1]=stack[top-1]-stack[top];
top--;
break;
case ‘*‘:
stack[top-1]=stack[top-1]*stack[top];
top--;
break;
case ‘/‘:
if(stack[top]!=0) stack[top-1]=stack[top-1]/stack[top];
else{
printf("\n\t除零错误!\n");
exit(0); /*异常退出*/
}
top--;
break;
default:
d=0;
while(ch>=‘0‘&&ch<=‘9‘){
d=10*d+ch-‘0‘; /*将数字字符转化为对应的数值*/
ch=ex[t];t++;
}
top++;
stack[top]=d;
}
ch=ex[t];t++;
}
printf("\n\t计算结果:%g\n",stack[top]);
}
void main(){
trans();
compvalue();
}
标签:style os io 使用 ar for sp on c
原文地址:http://www.cnblogs.com/notlate/p/3961778.html