經典算法-算術表達式求值

網上找了幾個相關的代碼 可惜不滿足我的要求 修改如下

 

/*經典算法-算術表達式求值
析用堆棧解析算術表達式的基本方法。給出的示例代碼能解析任何包括+,-,*,/,()和0到9數字組成的算術表達式。

2 中綴表達式和後綴表達式

中綴表達式就是通常所說的算術表達式,比如(1+2)*3-4。

後綴表達式是指通過解析後,運算符在運算數之後的表達式,比如上式解析成後綴表達式就是12+3*4-。這種表達式可以直接利用棧來求解。

3 運算符的優先級

優先級 運算符 
1 括號() 
2 負號- 
3 乘方** 
4 乘*,除/,求餘% 
5 加+,減- 
6 小於<,小於等於<=,大於>,大於等於>= 
7 等於==,不等於!= 
8 邏輯與&& 
9 邏輯或|| 
大致的規律是,一元運算符 > 二元運算符 > 多元運算符。
*/

#include
<iostream>
#include
<string.h> 
#include
<stdlib.h>
using namespace std; 
template 
<class T>
class stack 
{
    
public:
    stack()
{top= -1;SIZE=2;buffer=new T[SIZE];}//SIZE=2(過小)用於測試PUSH函數 
    ~stack(){if(buffer) delete []buffer;};//析構函數
    bool push(T element); //入棧
    T& pop();//出棧
    int size(){return top+1;};//取元素個數
    bool isempty()return top==-1;} 
    
void clear(){ top=-1;}
    
private:
    T 
*buffer;
    
int top;
    
int SIZE;
}
;
template 
<class T>
 
bool stack<T>::push(T element)
{
    top
++;
    
if (top>SIZE-1)
     
{
         SIZE
+=10;
         T
* temp  =new T [SIZE];
       
//  for(int i=0;i<SIZE-10;i++)
      
// temp[i]=buffer[i];//將對象 COPY 
         memcpy((void*)temp,(void*)buffer,(SIZE-10)*sizeof(T));//兩種方法都可 
         delete buffer;
         buffer
=temp;
     }
//滿
    buffer[top]=element;
    
return true;
}

template 
<class T> 
T
& stack<T>::pop()
{
     
return buffer[top--];
}
 
bool IsOperand( char ch )
{
    
char operators[] = '+''-''*''/''('')' };
    
for(int i=0; i<6; i++)
        
if( ch == operators[i] )
            
return false;
    
return true;
}

int Priority( char ch )
{
    
int priority;
    
switch( ch )
    
{
        
case '+' : 
            priority 
= 1;
            
break;
        
case '-' :
            priority 
= 1;
            
break;
        
case '*' :
            priority 
= 2;
            
break;
        
case '/' :
            priority 
= 2;
            
break;
        
default :
            priority 
= 0;
            
break;
    }

    
return priority;
}

double GetValue(char op, double ch1, double ch2)
{
    
switch( op )
    
{
        
case '+':
            
return ch2 + ch1;
        
case '-':
            
return ch2 - ch1;
        
case '*':
            
return ch2 * ch1;
        
case '/':
            
return ch2 / ch1;
        
default:
            
return 0;
    }

}

//將中綴表達式解析成後綴表達式
/*
中綴表達式翻譯成後綴表達式的方法如下:
(1)從右向左依次取得數據ch。
(2)如果ch是操作數,直接輸出。
(3)如果ch是運算符(含左右括號),則:
      a:如果ch = '(',放入堆棧。
      b:如果ch = ')',依次輸出堆棧中的運算符,直到遇到'('爲止。
      c:如果ch不是')'或者'(',那麼就和堆棧頂點位置的運算符top做優先級比較。
          1:如果ch優先級比top高,那麼將ch放入堆棧。
          2:如果ch優先級低於或者等於top,那麼輸出top,然後將ch放入堆棧。
(4)如果表達式已經讀取完成,而堆棧中還有運算符時,依次由頂端輸出。
如果我們有表達式(A-B)*C+D-E/F,要翻譯成後綴表達式,並且把後綴表達式存儲在一個名叫output的字符串中,可以用下面的步驟。

(1)讀取'(',壓入堆棧,output爲空
(2)讀取A,是運算數,直接輸出到output字符串,output = A
(3)讀取'-',此時棧裏面只有一個'(',因此將'-'壓入棧,output = A
(4)讀取B,是運算數,直接輸出到output字符串,output = AB
(5)讀取')',這時候依次輸出棧裏面的運算符'-',然後就是'(',直接彈出,output = AB-
(6)讀取'*',是運算符,由於此時棧爲空,因此直接壓入棧,output = AB-
(7)讀取C,是運算數,直接輸出到output字符串,output = AB-C
(8)讀取'+',是運算符,它的優先級比'*'低,那麼彈出'*',壓入'+",output = AB-C*
(9)讀取D,是運算數,直接輸出到output字符串,output = AB-C*D
(10)讀取'-',是運算符,和'+'的優先級一樣,因此彈出'+',然後壓入'-',output = AB-C*D+
(11)讀取E,是運算數,直接輸出到output字符串,output = AB-C*D+E
(12)讀取'/',是運算符,比'-'的優先級高,因此壓入棧,output = AB-C*D+E
(13)讀取F,是運算數,直接輸出到output字符串,output = AB-C*D+EF
(14)原始字符串已經讀取完畢,將棧裏面剩餘的運算符依次彈出,output = AB-C*D+EF/-
*/

char* Parse(const char *expr)
{
  
//  const char *exp = expr;
    int i, j = 0;
    
char ch, ch1;
    
const char* A = expr; 
    
char *B  = new char[strlen(expr)+1]; //最後生成的後綴表達式
    stack<char>  myStack;
    
for(i=0;ch = A[i]; i++)///A[I]='
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章