表示式計算(棧的應用)
題目描述
給出一個表示式,其中運算子僅包含+,-,*,/,^(加 減 乘 整除 乘方)要求求出表示式的最終值。
資料可能會出現括號情況,還有可能出現多餘括號情況。
資料保證不會出現大於或等於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;
}
相關文章
- 使用棧實現表示式求值,運用棧計算
- 棧的應用---字尾表示式
- 使用棧結構計算中綴表示式
- 簡單計算器(棧的應用)
- Lambda 表示式的應用
- 函式計算——應用初探函式
- 計算中綴表示式
- 正規表示式的應用
- 簡單計算器 (關於棧的一種應用)
- 一個數學表示式的計算
- 表示式的動態解析和計算,Flee用起來真香
- Java中Lambda表示式的應用Java
- 將算數表示式轉換成字尾表示式並計算結果
- 函式計算-HelloWorld應用開發函式
- C語言- 基礎資料結構和演算法 - 09 棧的應用_中綴表示式轉字尾表示式20220611C語言資料結構演算法
- 棧的應用
- JDK1.8中Lambda表示式的應用JDK
- 【資料結構與演算法】中綴表示式轉字尾表示式以及字尾表示式的計算資料結構演算法
- 【計算機演算法】 求字首表示式的值計算機演算法
- 函式計算實踐——一個應用案例函式
- mapboxgl 中插值表示式的應用場景
- Python中lambda表示式的語法與應用Python
- Lambda表示式基本語法與應用
- C#字尾表示式解析計算字串公式C#字串公式
- Linkedlist的應用場景:設計佇列、設計棧佇列
- 關於利用STL棧求解四則中綴表示式以及中綴表示式轉逆波蘭表示式和逆波蘭表示式的求解
- 棧的實際應用
- 棧的原理與應用
- 計算機資料的表示計算機
- leetcode 224. 基本計算器(逆波蘭表示式)LeetCode
- 算數表示式求值--c語言課程設計C語言
- c++虛擬函式實現計算表示式子C++函式
- 正規表示式的應用實現郵箱輸入
- 正規表示式如何在PHP裡靈活的應用PHP
- “暈乎乎的概念”:阿里雲函式計算的“應用”又是個啥阿里函式
- 逆波蘭表示式求值——棧與佇列佇列
- 【棧】【字串語法】牛牛與字尾表示式字串
- 亞馬遜雲科技全棧式Serverless,不止於計算亞馬遜全棧Server