算符优先分析法求解逆波兰式

算符优先分析法转中缀表达式为后缀表达式,求解

#include <iostream>
#include <stdlib.h>
#define N 20
#define M 8
using namespace std;
//4*(28+87*6-75)/8#
int location=0;
char final[M] ={'+','-','*','/','(',')','#'};
char table[M][M]=	{{'0','0','1','1','1','0','0'}, //算符优先分析表 
					{'0','0','1','1','1','0','0'},
					{'0','0','0','0','1','0','0'},
					{'0','0','0','0','1','0','0'},
					{'1','1','1','1','1','2','0'},
					{'1','1','1','1','1','0','0'},
					{'1','1','1','1','1','1','1'}};

char result[N][N];									
char sentence[N*10];

typedef struct{
	char *base;
	char *top;
	int size;
}Stack;

typedef struct{
	double *base;
	double *top;
	int size;
}stack;

void initstack(stack &s) {
	s.base=(double*)malloc(sizeof(double));
	s.top=s.base;
	s.size=0;
}

void appendstack(stack &s,double e) {
	stack ss;
	s.size++;
	ss.size=s.size;
	ss.base=(double *)malloc(ss.size*sizeof(double));
	ss.top=ss.base;
	for(int i=0;i<s.size-1;i++) {
	*ss.top++=*s.base++;
}
	*ss.top++=e;
	s=ss;
}

double popstack(stack &s) {
	
	s.top--;
	s.size--;
	return *s.top;
} 

void showStack(Stack s) {//展示栈的元素 
	
	for(int i=0;i<s.size;i++) {
		cout<<*s.base++;
	}

void showstack(stack s) {//计算后缀表达式的暂存栈显示栈的元素 
	
	for(int i=0;i<s.size;i++) {
		cout<<*s.base++<<" ";
	}
	cout<<endl;

}
char gettop(Stack s) {
	return *(--s.top);
}
void appendStack(Stack &s,char e) {
	Stack ss;
	s.size++;
	ss.size=s.size;
	ss.base=(char *)malloc(ss.size*sizeof(char));
	ss.top=ss.base;
	for(int i=0;i<s.size-1;i++) {
	*ss.top++=*s.base++;
}
	*ss.top++=e;
	s=ss;
}
void CreateStack(Stack &s) {
	s.base=(char*)malloc(sizeof(char));
	s.top=s.base;
}
char popStack(Stack &s) {
	if(s.top==s.base) {
	cout<<"空\n";
	return 1;}

	s.size--;
	return *(--s.top);
} 
void initStack(Stack &s) {
	s.base=(char*)malloc(sizeof(char));
	s.top=s.base;
	s.size=0;
}		
int gettopfinal(Stack s) {//得到最顶的终结符以便进行优先级比较 
	--s.top;
	int flag=0;
	int left=-1;
	while (flag==0) {
		
	for (int i=0;i<M;i++) {
		if(*s.top==final[i]) {
			flag=1;
			left=i;
			break;
		}
		
	}
	
	--s.top;
	}

	return left;
}
int isfinal(char c) {//判断是不是终结符 
	//int flag=0;
	
	for(int i=0;i<N;i++) {
		if (c==final[i]) {
			return i;	
		}
	}
	
	return -1;
}
int searchright(char *word,int locate) {
	int right=0;

	for (int i=0;i<M;i++) {
		if(word[locate]==final[i]) {
			right=i;
		}
	}//找到右边字符 
	return right;
}
void show(Stack s,int locate,char *word) {//输出剩余字符串 
	
	showStack(s);
	cout<<"\t\t";
	while (word[locate]!='\0') {
		cout<<word[locate];
		locate++;
	}
	//cout<<endl;
}
void guiyue(int left,Stack &s) {
	Stack ss;
	initStack(ss);
	char *p=--s.top;
	int i=1;
	int temp;
	result[location][0]=location+'a';
	while(s.top!=s.base) {
		 
		if(isfinal(*p)==-1){
			appendStack(ss,*p);
			p--;			
		}
		else if(*p==final[left]) {
			appendStack(ss,'&');
			temp=*p;
			//appendStack(ss,*p);
			p--;
		}
		else if(table[isfinal(*p)][left]=='1') {
		
			while(s.top!=p) {
				popStack(s);

			}
			appendStack(ss,temp);
//			showStack(ss);
			result[location][0]=location+'a';
			appendStack(s,location+'a');
			temp=popStack(ss);
			while (ss.base!=ss.top) {
				result[location][i++]=popStack(ss);
			}
			result[location][i]=temp;
			location++;
			break;
		}	
	}

	cout<<endl;
}

void guiyue1(int left,Stack &s ) {
	Stack ss;
	initStack(ss);
	char *p=--s.top;
	int i=1;
	int temp;
	result[location][0]=location+'a';
	while (s.base!=s.top) {
		if(isfinal(*p)==-1) {
			appendStack(ss,*p);
			p--;
		}
		
		else if(isfinal(*p)==left) {
			p--;
		}
		else if(table[isfinal(*p)][left]=='2') {
			while (s.top!=p) {
				popStack(s);
			}
			appendStack(ss,popStack(s));
			result[location][0]=location+'a';
			appendStack(s,location+'a');
			popStack(ss);
			
			while (ss.base!=ss.top) {
				result[location][i++]=popStack(ss);
			}
			//result[location][i]=temp;
			location++;
			break;
			
		}
	}
}

int size=0;

int connect(int i) {
		int loc1=1;
		if(i<0) {
			return 0;
		}
		
		while (result[i][loc1]!='\0') {
			
			if(result[i][loc1]>='a'&&result[i][loc1]<='z') {
				//cout<<result[i][loc1]<<endl;
				for(int j=0;j<location;j++) {
					//loc2=1;
					if(result[j][0]==result[i][loc1]) {
						connect(j);
						break;
					//	return 0;
					}
				}
				loc1++;
			
			}
			 
			else {
				
				sentence[size++]=result[i][loc1++];
				//cout<<"跳转"<<result[i][loc1]<<endl;
			}
			
		}
//		connect(--i);
		return 0;
}
void deal() {
	for(int i=1;i<size;i++) {
		if(sentence[i]=='&') {
			if(sentence[i-1]<'0'||sentence[i-1]>'9') {
				for(int j=i;j<size;j++) {
					sentence[j]=sentence[j+1];
				}
				size--;
			}
		}
	}
	
		cout<<"逆波兰式为:"<<sentence<<endl;
	
}
void anysis(char * word,Stack &s) {
	int locate=0;
	int left=0;
	int right;
	while (word[locate]!='\0') {
		
		while (isfinal(word[locate])==-1) {
			//show(s,locate,word);	
			appendStack(s,word[locate]);
			locate++;	
		};//数字进栈 
		
		left=gettopfinal(s);
		right=searchright(word,locate);	
		//show(s,locate,word);
		switch(table[left][right]) {
		
		case '0' :guiyue(left,s);break;
		case '2' :appendStack(s,word[locate]);left=gettopfinal(s);guiyue1(left,s);locate++;break;//
		case '1' :appendStack(s,word[locate]);locate++;break;
		//case '3' :cout<<"\t不匹配"<<endl;flag=1;break;
		
		}

	}
}
int calculate() {
	stack s;
	initstack(s);
	int i=0;
	double x1;
	double x2;
	while (sentence[i]!='\0') {
		if(sentence[i]=='+') {
			x2=popstack(s);
			x1=popstack(s);
			appendstack(s,x1+x2);
			//showstack(s);
			i++;
		}
		else if(sentence[i]=='-') {
			x2=popstack(s);
			x1=popstack(s);
			appendstack(s,x1-x2);
			//showstack(s);
			i++;
		}
		else if(sentence[i]=='/') {
			x2=popstack(s);
			x1=popstack(s);
			appendstack(s,x1/x2);
			//showstack(s);
			i++;
		}
		else if(sentence[i]=='*') {
			x2=popstack(s);
			x1=popstack(s);
			appendstack(s,x1*x2);
			//showstack(s);
			i++;
		}
		else if(sentence[i]!='&') {
			if(sentence[i+1]>='0'&&sentence[i+1]<='9') {
			//	cout<<sentence[i]<<" "<<sentence[i+1]<<endl;
				appendstack(s,(sentence[i]-'0')*10+(sentence[i+1]-'0'));
				//showstack(s);
				i=i+2;
			}
			else {
			//	cout<<sentence[i]<<" \n";
				appendstack(s,sentence[i]-'0');
				//showstack(s);
				i++;
			}
		}
		else i++;
	}
	cout<<"逆波兰式test"<<sentence<<"=计算结果为";
	showstack(s);
}
int main () {
	
	Stack s;
	initStack(s);
	appendStack(s,'#');
	char word[N];

	cout<<"输入一串以#结束的中缀表达式(包括+-*/()数字#)"<<endl;
	cin>>word;
	anysis(word,s); 
	connect(--location);

	deal();
	calculate();
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值