從鍵盤輸入中綴表達式,創建操做數與運算符堆棧,計算並輸出表達式的求值結果。
基本要求:實現 +, -, *, /四個二元運算符以及();操做數範圍爲0至9。
提升要求:實現+, -兩個一元運算符(即正、負號);操做數可爲任意整型值(程序可不考慮計算溢出)。
若兩個整數相除,結果只保留整數商(餘數丟棄);可不處理表達式語法錯誤。ios
棧與隊列算法
採用C++的模板類,分別建立元素類型爲整型的操做數棧OPND和字符型的運算符棧OPTR,每一個棧對象中,elem指針用來創建長度爲n的數組,n表示棧中元素的最大個數,top表示棧頂指針。數組
①中綴表達式以'#'結束,'#'字符也作運算符處理。
②'('、')'做爲運算符處理,括號內運算結束後須要消除括號。
③須要創建兩個不一樣類型的棧,整型的操做數棧OPND和字符型的運算符棧OPTR。
④算法主要步驟:
a. 初始時,OPND置空,'#'做爲OPTR棧底元素;
b. 依次讀入表達式中的每一個字符,如果操做數,直接壓入OPND棧;
c. 如果運算符(記爲θ),PTR棧頂運算符(爲λ)優先級;
λ<θ,θ壓入OPTR棧,繼續讀下一個字符;
λ=θ,脫括號,繼續讀下一個字符;
λ>θ,執行λ運算(λ退棧),θ等在棧外(不讀下一個字符),即θ繼續和OPTR 棧頂運算符比較優先級(重複進行以上操做),直至θ能入棧。
⑤對於一元運算符(即正、負號),用'P'表明'+','N'表明'-'。數據結構
#include<iostream> using namespace std; template <typename T> class Stack //模板類:棧 { public: Stack(); //默認構造函數 Stack(int n); //構造函數,調用函數createStack(int n),建立長度爲n的棧 ~Stack(); //虛構函數 int createStack(int n); //建立長度爲n的棧 int empty(); //判斷棧是否爲空 int full(); //判斷棧是否爲滿 int push(T e); //將元素e壓棧 int pop(T &e); //元素出棧,保存在e中 T get_top(); //獲得棧頂元素 friend int isoperator(char &e);//判斷字符e是否爲運算符 friend int isp(char &e);//返回棧中運算符的優先級 friend int icp(char &e);//返回棧外運算符的優先級 friend int compute(int x, char a, int y);//求值函數 private: T *elem; //創建長度爲n的數組 int n; //棧中元素的最大個數 int top; //棧頂指針 }; template<typename T> Stack<T>::Stack() { top = -1; } template<typename T> Stack<T>::Stack(int n) { createStack(n); } template<typename T> Stack<T>::~Stack() { n = 0; top = -1; delete[]elem; } template<typename T> int Stack<T>::createStack(int n) { if (n <= 0) return 0; this->n = n; top = -1; elem = new T[n]; if (!elem) return 0; return 1; } template<typename T> int Stack<T>::empty() { return top == -1; } template<typename T> int Stack<T>::full() { return top >= n - 1; } template<typename T> int Stack<T>::push(T e) { if (top >= n - 1) return 0; elem[++top] = e; return 1; } template<typename T> int Stack<T>::pop(T & e) { if (top == -1) return 0; e = elem[top--]; return 1; } template<typename T> T Stack<T>::get_top() { return elem[top]; }; int isoperator(char &e) //判斷是否爲運算符 { if (e == '+' || e == '-' || e == '*' || e == '/' || e == '(' || e == ')' || e == '#' || e == 'P' || e == 'N') return 1; //是運算符返回1 else return 0; //不是運算符返回0 } int isp(char &e) //返回棧中運算符的優先級 { switch (e) { case '#': return 0; break; case '(': return 1; break; case '+': case '-': return 2; break; case '*': case '/': return 3; break; case 'P': case 'N': return 4; break; case ')': return 5; break; default: return -1; break; } } int icp(char &e) //返回棧外運算符的優先級 { switch (e) { case '#': return 0; break; case ')': return 1; break; case '+': case '-': return 2; break; case '*': case '/': return 3; break; case 'P': case 'N': return 4; break; case '(': return 5; break; default: return -1; break; } } int compute(int x, char a, int y) { switch (a) { case '+': //計算加法 return x + y; break; case '-': //計算減法 return x - y; break; case '*': //計算乘法 return x * y; break; case '/': //計算除法 return x / y; break; default: return -1; break; } } int g1() { char a, b, c; int i, j, f, value, firstOpnd, secondOpnd, m; Stack<char> OPTR(MAX); //創建運算符棧 Stack<int> OPND(MAX); //創建操做數棧 OPTR.push('#'); //'#'壓棧 cout << "請輸入中綴表達式: "; a = getchar(); while (a != '#' || OPTR.get_top() != '#') { if (!isoperator(a)) //不是運算符,即爲操做數,操做數入棧 OPND.push(a - 48);//將字符型轉化爲整型數字 else //是運算符,與棧頂運算符比較優先級大小 { b = OPTR.get_top();//獲得棧頂元素 i = isp(b); //棧頂運算符的優先級 j = icp(a); //棧外運算符的優先級 if (i < j) //棧外運算符優先級高,運算符入棧 OPTR.push(a); else { OPTR.pop(b); if (b != '('&&i == j || i > j) { c = OPTR.get_top(); if ((c == '(' || c == '#') && (b == 'P' || b == 'N')) /*c爲一元運 算符:正負號*/ { OPND.pop(firstOpnd); //獲得操做數 switch (b) { case 'P': //正號 f = firstOpnd * 1; break; case 'N': //負號 f = firstOpnd * (-1); break; } } else //c爲二元運算符 { OPND.pop(secondOpnd); //獲得第二操做數 OPND.pop(firstOpnd); //獲得第一操做數 f = compute(firstOpnd, b, secondOpnd); //計算求值 } OPND.push(f); //求值結果壓棧 continue; } } } c = a; a = getchar(); //繼續讀取字符 while(!isoperator(a) && !isoperator(c)) /*若連續讀取字符均爲數字,則乘以位權 獲得多位數*/ { OPND.pop(m); m = m * 10 + a - 48; OPND.push(m); c = a; a = getchar(); } } OPND.pop(value); return value; //返回表達式的結果 } int main() { int a; a = g1(); cout << "運算結果爲: " << a << endl; return 0; }
(1)程序輸入:3+5*(9-5)/10#
程序輸出:5函數
(2)程序輸入:P9+10*(N2*8/4)-10#
程序輸出:-41this
(3)程序輸入:20-3*25+(N41/3)*100#
程序輸出:-1355spa