表达式求值:
表达式求值是程序设计语言编译中的一个基本问题,任何一个表达式都有操作数、运算法则和界限符组成。其中操作数可以是常量、变量或常量标识符。运算符可以分为算术运算符、关系运算符和逻辑运算符。
对于表达式的记法主要有三种:前缀表达式(波兰式)、中缀表达式和后缀表达式(逆波兰式),它们之间的区别在于运算符相对于操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前,中缀表达式的运算符位于与其相关的操作数中间,而后缀表达式的运算符位于与其相关的操作数之后。例如给定表达式: ( a + b ) * ( c - d / e ) - f ;
前缀表达式: - * + a b - c / d e f
中缀表达式: a + b * c - d / e - f
后缀表达式:a b + c d e / - * f -
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>
#include<iostream>
#define SElemType int
#define inf 0x3f3f3f3f
using namespace std;
typedef struct LNode{
SElemType data;
struct LNode *next;
LNode (SElemType Data=0,struct LNode * Next=NULL){
data=Data;
next=Next;
}
}LNode ,*LinkList ;
void InitStack(LinkList &LS){
LS=NULL;
}
bool StackEmpty(LinkList LS){
return LS?false:true;
}
int StackLength(LinkList Ls){
int cnt=0;
LinkList p=Ls;
while(p){
cnt++;p=p->next;
}
return cnt;
}
void Push(LinkList &LS,SElemType e){
LinkList s;
s=new LNode(e,LS);
LS=s;
}
void Pop(LinkList &LS,SElemType &e){
if(LS==NULL){
printf("error !!! Stack is empty !\n");
return ;
}
e=LS->data;
LinkList s=LS;
LS=LS->next;
delete s;
}
void GetTop(LinkList LS,SElemType &e){
if(!LS){
printf("error !!! Stack is empty !\n");
return ;
}
e=LS->data;
}
char Prior[10][10]={
">><<<>>",
">><<<>>",
">>>><>>",
">>>><>>",
"<<<<<= ",
">>>> >>",
"<<<<< ="
};
int Operator(int a,char theta,int b){
if(theta=='/'&&!b){
return inf*printf(" error!!! \"/0\" ");
}
switch(theta){
case '+': return a+b; break;
case '-': return a-b; break;
case '*': return a*b; break;
case '/': return a/b; break;
}
}
char Oper[]="+-*/()#";
int Locate(char theta){
for(int i=0;i<7;i++)
if(theta==Oper[i])
return i;
return -1*printf("error !!! theta is wrong \n");
}
char Compare(char theta1 , char theta2){
int i=Locate(theta1);
int j=Locate(theta2);
if(~i&&~j)
return Prior[i][j];
}
void EvaluateExpression(char str[]){
LinkList Optr,Opnd;
printf("%s = ",str);
char *p=str;
int len=strlen(str);
str[len]='#';
str[len+1]='\0';
int ch,theta;
int a,b;
InitStack(Optr);
Push(Optr,'#');
InitStack(Opnd);
while(*p=='\0'||*p!='#'||ch!='#'){
if(*p==' '){
p++;
}else if(*p>='0'&&*p<='9'){
int num=0;
while(*p!='#'&&*p>='0'&&*p<='9'){
num=num*10+(*p-'0');
p++;
}
//printf("Num = %d\n",num);
Push(Opnd,num);
}
else{
GetTop(Optr,ch);
//printf("%c\n",ch);
switch(Compare(ch,*p)){
case '<': Push(Optr,*p);p++; break;
case '=': Pop(Optr,ch); p++; break;
case '>': Pop(Opnd,b),Pop(Opnd,a);Pop(Optr,theta);
//printf("%d %c %d = %d\n",a,theta,b,Operator(a,theta,b));
Push(Opnd,Operator(a,theta,b));
break;
}
}
GetTop(Optr,ch);
}
GetTop(Opnd,a);
//return a;
printf("%d\n",a);
}
void EvaluatePreExpression(char str[]){
int n=strlen(str),a,b;
char *p=str+n-1;
LinkList Opnd;
InitStack(Opnd);
while(n>0){
if(*p==' '){
p--;n--;
}else if('0'<=*p&&*p<='9'){
LinkList S;
InitStack(S);
while(*p!=' '&&'0'<=*p&&*p<='9'){
Push(S,*p-'0');
p--;n--;
}
int num=0,ch,e;
while(!StackEmpty(S)){
Pop(S,e);
num=num*10+e;
}
Push(Opnd,num);
}else{
/*
if(Locate(*p)>=0){
printf("p = '%c'\n",*p);
}
*/
Pop(Opnd,a); Pop(Opnd,b);
Push(Opnd,Operator(a,*p,b));
p--;n--;
}
}
GetTop(Opnd,a);
printf("%s = %d\n",str,a);
//return a;
}
void EvaluatePostExpression(char *str){
char *p = str;
LinkList Opnd;
InitStack(Opnd);
int a,b;
while(*p!='\0'){
if(*p==' '){
p++;
}else if('0'<=*p&&*p<='9'){
int num=0;
while('0'<=*p&&*p<='9'){
num=num*10+*p-'0';
p++;
}
Push(Opnd,num);
}else{
Pop(Opnd,b);Pop(Opnd,a);
Push(Opnd,Operator(a,*p,b));
p++;
}
}
GetTop(Opnd,a);
//return a;
printf("%s = %d\n",str,a);
}
void get_s(char *s){
char ch=getchar();
int cnt=0;
while(ch!='\n'){
s[cnt++]=ch;
ch=getchar();
}
s[cnt]='\0';
}
void Warning(int n=5){
if(n==-1){
puts("\t\t********************************");
puts("\t\t** **");
puts("\t\t**请选择一种表达式来进行计算:**");
puts("\t\t** **");
puts("\t\t** 1、前缀表达式: **");
puts("\t\t** 2、中缀表达式: **");
puts("\t\t** 3、后缀表达式: **");
puts("\t\t** 0、退出 **");
puts("\t\t** **");
puts("\t\t********************************");
puts("");
printf("\t\t请选择其中一项:");
}else if (n==-2){
printf("\t\t");
}else if(n==0){
puts("\t\t退出程序");
}else if(n==1){
puts("\t\t请输入前缀表达式:");
printf("\t\t");
}else if(n==2){
puts("\t\t请输入中缀表达式:");
printf("\t\t");
}else if (n==3){
puts("\t\t请输入后缀表达式:");
printf("\t\t");
}else {
puts("\t\t输入错误,请重新输入!!!");
}
}
int main()
{
int ans,No;
while(1){
No=-3;
char s[100]="\0",t[100];
Warning(-1);
scanf("%s",t);
getchar();
if(strlen(t)==1){
No=t[0]-'0';
}
Warning(No);
switch(No){
case 0: return 0;
case 1: get_s(s);Warning(-2);EvaluatePreExpression(s); break;
case 2: get_s(s);Warning(-2);EvaluateExpression(s); break;
case 3: get_s(s);Warning(-2);EvaluatePostExpression(s);break;
}
Sleep(2000);
system("cls");
}
return 0;
}