表示式計算(棧的應用)
題目描述
給出一個表示式,其中運算子僅包含+,-,*,/,^(加 減 乘 整除 乘方)要求求出表示式的最終值。
資料可能會出現括號情況,還有可能出現多餘括號情況。
資料保證不會出現大於或等於231的答案。
資料可能會出現負數情況。
輸入格式
輸入僅一行,即為表示式。
輸出格式
輸出僅一行,既為表示式算出的結果。
輸入樣例:
(2+2)^(1+1)
輸出樣例:
16
題解
- 從前往後掃描字串。維護兩個棧,一個數字棧,儲存數字。一個運算子棧,儲存運算子。
- 如果是數字就壓入數字棧中。
- 如果是‘(’ 就壓入運算子棧中。
- 如果是‘ )’ 就結算整個括號,並且刪除從運算子棧中刪除‘(’。
- 如果是 ‘+’ 或‘ - ’或‘ * ’ 或‘ / ’ 或乘方,就結算前面優先順序高或等於當前運算子。
程式碼
#include <iostream>
#include <stack>
#include <string>
using namespace std;
stack<int> nums;
stack<char> ops;
//快速冪
int qmi(int a, int b)
{
int res = 1;
while(b)
{
if(b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
//計算
void cal()
{
int a = nums.top(); nums.pop();
int b = nums.top(); nums.pop();
char c = ops.top(); ops.pop();
int d;
if(c == '+') d = a + b;
else if(c == '-') d = b - a;
else if(c == '*') d = b * a;
else if(c == '/') d = b / a;
else d = qmi(b, a);
nums.push(d);
}
int main()
{
string str;
cin >> str;
if(str[0] == '0') str = '0' + str; //-(1 + 1)
string left;
for(int i = 0; i < str.size(); i++) left += "(";
str = left + str + ")"; //保證左括號數量大於右括號
for(int i = 0; i < str.size(); i++)
{
if(str[i] >= '0' && str[i] <= '9')
{
int j = i, t = 0; //多位數字
while(j < str.size() && str[j] >= '0' && str[j] <= '9')
{
t = t * 10 + str[j] - '0';
j++;
}
i = j - 1;
nums.push(t);
}
else
{
char c = str[i];
if(c == '(') ops.push(c);
else if(c == '+' || c == '-')
{
if(c == '-' && i && !(str[i - 1] >= '0' && str[i - 1] <= '9') && str[i - 1] != ')') //'-' 代表負號
{
if(str[i + 1] == '(') // 將-(...)變成-1 * (...)
{
nums.push(-1);
ops.push('*');
}
else
{
int j = i + 1, t = 0;
while(j < str.size() && str[j] >= '0' && str[j] <= '9')
{
t = t * 10 + str[j] - '0';
j++;
}
nums.push(-t);
i = j - 1;
}
}
else //將 + - 號前面的運算子優先順序高的結算,加,減優先順序最低。前面都可以結算
{
while(ops.top() != '(') cal();
ops.push(c);
}
}
else if(c == '*' || c == '/')將 * / 號前面的運算子優先順序高或等於的結算
{
while(ops.top() == '*' || ops.top() == '/' || ops.top() == '^') cal();
ops.push(c);
}
else if(c == '^') 將 '^' 號前面的運算子優先順序高或等於的結算
{
while(ops.top() == '^') cal();
ops.push(c);
}
else if(c == ')') // 將整個括號結算
{
while (ops.top() != '(') cal();
ops.pop(); //刪除'('
}
else cout << "invalid operator!" << endl;
}
}
cout << nums.top() << endl;
return 0;
}
相關文章
- 表示式計算 用棧完成
- 使用棧實現表示式求值,運用棧計算
- 棧的應用——表示式求和
- 棧的應用---字尾表示式
- 棧在表示式求值中的應用
- 【資料結構】棧的應用---四則運算表示式求值(中綴表示式與字尾表示式轉換)資料結構
- 使用棧結構計算中綴表示式
- 簡單計算器(棧的應用)
- 棧的應用——計算器的四則運算
- 【資料結構】棧的應用——中綴表示式求值(c++)資料結構C++
- Lambda 表示式的應用
- 計算中綴表示式
- 函式計算——應用初探函式
- 簡單計算器 (關於棧的一種應用)
- excel 計算文字型數學表示式 用 evaluateExcel
- 正規表示式的應用
- 資料結構學習(C++)——棧應用(表示式求值) (轉)資料結構C++
- 一個數學表示式的計算
- PG 中表示式的計算順序
- 表示式的動態解析和計算,Flee用起來真香
- 將算數表示式轉換成字尾表示式並計算結果
- 函式計算-HelloWorld應用開發函式
- 棧(2)--棧的應用
- 正規表示式應用收集
- Java正規表示式應用Java
- 連結串列與棧的典型應用——簡單計算機的實現計算機
- 棧的應用
- python--表示式(運算表示式)Python
- 33:計算分數加減表示式的值
- 表示式編譯計算器(下) (轉)編譯
- JDK1.8中Lambda表示式的應用JDK
- Java 正規表示式的簡單應用.Java
- 正規表示式在PHP裡的應用PHP
- 【資料結構與演算法】中綴表示式轉字尾表示式以及字尾表示式的計算資料結構演算法
- [.net 物件導向程式設計進階] (7) Lamda表示式(三) 表示式樹高階應用物件程式設計
- 【計算機演算法】 求字首表示式的值計算機演算法
- 函式計算實踐——一個應用案例函式
- 表示式計算原始碼JAVA實現 (轉)原始碼Java