表達式求值

表達式求值是高級語言編譯中的一個基本問題,是棧的典型應用實例。任何一個表達式都是由運算對象,運算符和界限符組成的。運算對象既可以是常數,也可以是被說明爲變量或常量的標識符;運算符可以分爲算術運算符,關係運算符和邏輯運算符三類;基本界限符有括號和表達式結束符等。
算法思想
1.規定運算符的優先級表。
2.設置兩個棧,)OVS(運算數棧),OPTR(運算符棧)。
3,自左向右掃描,進行如下處理。
若遇到運算數則進入OVS棧,若遇到運算符則與OPTR棧的棧頂運算符進行有限比較:
如果當前運算符優先級大於OPTR棧頂運算符優先級,則當前運算符進OPTR棧、
如果當前運算符優先級小於等於OPTR棧頂運算符優先級,則OPTR退棧一次,得到棧頂運算符&,連續退OVS棧兩次,得到運算數a 運算數b,對a b執行&運算,得到結果T,將T進OVS棧。
算法描述

#include<iostream>

using namespace std;

typedef char StackElementType;//棧數據類型

typedef struct StackNode{
  StackElementType data; // 數據
  StackNode *next; //指針
}LinkStackNode,*LinkStack;

//定義一個運算符數組集合
StackElementType opSet[]={"+-*/#"};

//初始化棧 
void initStack(LinkStack &top){
  LinkStack p;
  p = (LinkStack)malloc(sizeof(LinkStackNode));//申請一個空間作爲頭結點
  top = p; //頭指針指向頭結點
  p->next = NULL; //空棧
}

//操作:進棧
bool push(LinkStack &top,StackElementType data){
    LinkStack p;
	p = (LinkStack)malloc(sizeof(LinkStackNode));//申請一個棧的空間
	if(p == NULL)
      return false; //申請空間失敗
	//申請成功
    p->data = data; //在申請的空間中放入一個數據

	p->next = top;// 壓棧
	top = p;//top指向棧頂
	return true;
}
//出棧並返回出棧的值
bool pop(LinkStack &top,StackElementType &data){
   LinkStack p;
   p = top; //p爲棧頂 
   if(p->next== NULL) //棧爲空
	 return false;
   //棧不爲空 
   top = p->next;//棧頂往下移一個
   data = p->data;//p就爲棧頂 ,要出棧的數據
   free(p);//釋放棧頂的空間
   return true;
}
//判斷字符是不是運算符,是運算符返回1不是返回0
bool inOpSet(StackElementType a,StackElementType b[]){
	int i = 0;
	int flag = 0;
    while(b[i]!='\0'){ //遍歷字符串
	 if(a == b[i])//有這個運算符 
		 return 1;
	  i++;
	}
    return 0;//沒有找到這個運算符
}
//轉換 把字符型數據轉換成整形
void getNumber(StackElementType &a){
  a = a - 48;//轉換
}
//獲取棧頂的元素,不改變原來棧的信息
StackElementType getTop(LinkStack top){

	return top->data;//返回棧頂元素
}
//給運算符賦優先級
int judgePriority(StackElementType op){
  int priority;//定義一個優先級
	switch(op){
	case '+':priority = 1;break;
	case '-':priority = 1;break;
	case '*':priority = 2;break;
	case '/':priority = 2;break;
	case '#':priority = 0;break;
	}
 return priority; //返回對應的優先級
}
//和棧頂的運算符進行比較,結果返回>或<或=
StackElementType compare(StackElementType a,StackElementType b){
	int aa = judgePriority(a);//看a的優先級
	int bb = judgePriority(b);//看b的優先級
   if(aa > bb)
	   return '>';
   else if(aa == bb)
	   return '=';
   else
	   return '<';
   
}
//計算兩個數的運算
int execute(int a,StackElementType op,int b){
  switch(op){//判斷是什麼運算
   case '+':
	       return a+b;
	       break;
   case '-':
	       return a-b;
	       break;
   case '*':
	       return a*b;
	       break;
   case '/':
	       return a/b;
	       break;
  }
}
//無括號表達式運算
int expEvaluation(){
  char ch;
  StackElementType a,b,op,n,result;
 LinkStack OPTR;//運算符棧
 LinkStack OVS; //運算數棧
 initStack(OPTR);//初始化棧
 initStack(OVS);
 push(OPTR,'#');//爲了便於操作,首先將#壓入OPTR棧
 ch = getchar();//輸入一個字符
 while(ch!='#'||getTop(OPTR)!='#'){//輸入的字符不爲#和棧頂的字符不爲#
   if(!inOpSet(ch,opSet)){//opSet是運算符集合
		getNumber(ch); //把字符數字變爲整形數字
	  push(OVS,ch);//把運算數壓入遠算數棧
	  ch = getchar();//再次輸入下一個字符
   }
   else  
    switch(compare(ch,getTop(OPTR))){//和棧頂的運算符進行比較優先級
	case '>':  //運算符優先級高
		     push(OPTR,ch); //壓棧
		     ch = getchar();//再次輸入字符
			 break;
    case '=':  //一樣優先級
	case '<':  //小於優先級
		     pop(OPTR,op);//出棧運算符
			 pop(OVS,b);//
			 pop(OVS,a);//出棧運算數
			 result = execute(a,op,b);//對ab進行運算
			push(OVS,result);//把結果再次壓入棧中
			break;
	}
   }
   result = getTop(OVS);//獲取計算最後的結果
   return result;//返回結果
}

//main函數,程序的入口地址
void main(){
 
 int result=expEvaluation();
 cout <<"計算最後的結果是:"<< result;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章