C++實現簡易計算器
#include <iostream>
#include <string>
#include <stack>
//#define fin cin
//#define fo
using namespace std;
bool isOperator(char x)
{
if(x=='('||x==')'||x=='+'||x=='-'||x=='*'||x=='/')
return true;
else
return false;
}
int getPriority(char x)
{
if(x=='+'||x=='-')
return 1;
if(x=='*'||x=='/')
return 2;
if(x=='(')
return 0;
}
bool isBracket(char x)
{
if(x=='('||x==')')
return true;
else
return false;
}
int doOperate(int d1,int d2,char t)
{
//cout<<d1<<" "<<t<<" "<<d2<<endl;
if(t=='+')
return (d1+d2);
if(t=='-')
return (d1-d2);
if(t=='*')
return (d1*d2);
if(t=='/')
return (d1/d2);
}
int main()
{
stack<int> Q;
stack<char> S;
string str;
cin>>str;
char x;
int opnum;
string temp="";//臨時存放運算元
int d2,d1;
char t;
//cout<<str.size()<<endl;
//cout<<str[str.size()-1]<<endl;
for(int i=0;i<str.size();i++)
{
x=str[i];
//cout<<x<<endl;
}
for(int i=0;i<str.size();i++)
{
x=str[i];
//cout<<x<<endl;
//如果是運算元
if(x>=48&&x<=57)
{
temp.append(1,x);
}
if(isOperator(x))
{
if(temp!="")
{
opnum=stoi(temp);
//cout<<opnum<<endl;
Q.push(opnum);
temp="";
}
if(S.empty())
S.push(x);
else{//棧中有一個(,然後壓入一個+,由於(的優先順序未知而出錯
if(x=='('||
((!isBracket(x))&&
(getPriority(x)>getPriority(S.top()))))
S.push(x);
else
if(x==')')
{
while(S.top()!='(')
{
d2=Q.top();
Q.pop();
d1=Q.top();
Q.pop();
t=S.top();
S.pop();
Q.push(doOperate(d1,d2,t));
}
S.pop();//彈出)
}
else
{
while(!S.empty()&&
((getPriority(S.top())>getPriority(x))||(getPriority(x)==getPriority(S.top()))))
{
d2=Q.top();
Q.pop();
d1=Q.top();
Q.pop();
t=S.top();
S.pop();
Q.push(doOperate(d1,d2,t));
}
S.push(x);
}
}
}
if(!isOperator(x)&&i==str.size()-1)
Q.push(stoi(temp));
}
while(!S.empty())
{
d2=Q.top();
Q.pop();
d1=Q.top();
Q.pop();
t=S.top();
S.pop();
Q.push(doOperate(d1,d2,t));
}
cout<<Q.top();
/*
if(Q.size()==2)
{
d2=Q.top();
Q.pop();
d1=Q.top();
Q.pop();
t=S.top();
S.pop();
Q.push(doOperate(d1,d2,t));
}
*/
return 0;
}
實現思想:一邊中綴轉字尾一邊計算,這樣只需要一次掃描就可以計算完畢,計算複雜度為O(n),計算步驟如下
處理某個x
- 判斷是運算元還是運算子
- 處理字元
- 如果是運算元,壓入運算元棧Q
- 如果是運算子,分為如下情況討論
-
如果運算子棧S為空,直接將x壓入S棧
-
如果運算子棧S不空,且x是'('或者x的優先順序大於棧頂元素優先順序,x壓棧
-
如果S不空,且x優先順序小於等於棧頂元素,彈棧處理至S為空或者x優先順序大於棧頂
-
如果x為')',處理至'('
當處理完所有字元之後,彈棧處理直到S為空,Q的棧頂即為所求
彈棧處理:取Q的兩個元素,目前棧頂為d2,將d2彈出之後的棧頂為d1,設操作符棧頂為t,則處理過程為計算 d1 t d2,然後後將d1 t d2壓棧,此過程中d1,d2, t都已經彈棧了
實現細節:
- 如何擷取運算元?兩個操作符(或者頭與操作符,操作符與尾)之間的為運算元
- 優先順序的判定?此處應該注意'(',因為與棧頂優先順序比較,如果不給'('設定一個優先順序在判斷時會產生錯誤,可以將(優先順序設定為最低。
- 短路與和短路或?會不會產生因為壓入一個'('就將之前的都計算的錯誤呢?因為上面的設定?不會的,因為在下面這句程式碼裡,我們會首先判斷是不是括號,如果滿足條件,不會計算||之後的條件,因為a||b這樣的判斷,如果a為真,不管b是否為真該語句都是真,所以不會判斷b條件,從而不會產生錯誤
if(x=='('||
((!isBracket(x))&&
(getPriority(x)>getPriority(S.top()))))
S.push(x);
while(!S.empty()&&
((getPriority(S.top())>getPriority(x))||(getPriority(x)==getPriority(S.top()))))
相關文章
- 前端 JavaScript 實現一個簡易計算器前端JavaScript
- JS_實現一個簡易計算器JS
- JavaScript實現一個簡易的計算器JavaScript
- C++簡易計算器自寫棧版C++
- python 的 Tkinter實現一個簡易計算器Python
- python簡易計算器Python
- C++程式設計_簡易計時器(Timer)的控制檯實現C++程式設計
- C++ 實現簡略計算π的程式C++
- 16_簡單計算器實現
- 使用QT做一個簡易計算器QT
- 手把手帶你利用棧來實現一個簡易版本的計算器
- 手寫實現java棧結構,並實現簡易的計算器(基於字尾演算法)Java演算法
- Java實現一個簡單的計算器Java
- QT簡易計算機制作QT計算機
- 用java實現一個簡單的計算器Java
- 教你python tkinter實現簡單計算器功能Python
- 1、簡單工廠模式實現計算器功能模式
- namedtuple簡易實現
- [C++ Daily] 使用模板實現簡易Python WrapperC++AIPythonAPP
- Mac簡易計時器Mac
- html+css+js製作一個簡易計算器HTMLCSSJS
- 用c++實現淨現值的計算C++
- 從0到1實現一個簡單計算器
- java 簡單工廠模式(實現一個計算器)Java模式
- 音樂播放器的實現(簡易版)播放器
- 簡易版 vue實現Vue
- 快捷簡易統計圖表模型設計與實現模型
- 實現一個簡易的靜態伺服器伺服器
- C++記憶體管理:簡易記憶體池的實現C++記憶體
- htmltest~計算器介面的實現HTML
- 簡易實現一個expressExpress
- 簡易RPC框架實現RPC框架
- 簡單計算器的程式導向實現和麵向物件實現對比物件
- 簡單c++實現複數的四則運算C++
- 利用ANTLR4實現一個簡單的四則運算計算器
- c++簡易小遊戲C++遊戲
- C++結合QT實現帶有優先順序的計算器C++QT
- 基於FFmpeg和Qt實現簡易影片播放器QT播放器