1. 程式人生 > 實用技巧 >計算2*3+(2*(5+6)*3)/2+4*6的值

計算2*3+(2*(5+6)*3)/2+4*6的值

程式碼弊端:

1.初始公式串的數值只能是0-9. 大於10的數字會有問題,可以改造myCopy函式

2. 計算順序是從左到右。 比如2*3*4是先算的2*3 再算的rusult*4. 貌似c語言是從又到左的計算順序

#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;


bool isOper(char val) { return ((val == '+') || (val == '-') ||(val == '*') || (val == '/') ||(val == '(') || (val == ')')); } //把char*字串拷貝到vector中 void myCopy(vector<char>& container, char* v) { while(*v != 0) { if (isOper(*v)) { container.push_back(*v); }
else { container.push_back(*v - '0'); } v++; } } void prtVecs(const vector<char>& values, const vector<int>& pris) { //列印權重串 for(auto pri : pris) { cout << " " << pri; } cout << endl; //列印公式串 for
(auto val : values) { if (isOper(val)) { cout << " " << val; } else { cout << " " << (int)val; } } cout << endl; } void prtVecs(const vector<char>& values) { //列印公式串 for(auto val : values) { if (isOper(val)) { cout << " " << val; } else { cout << " " << (int)val; } } cout << endl; } //加減乘除計算 int realCal(int first, char oper, int second) { if (oper == '+') return first + second; if (oper == '-') return first - second; if (oper == '*') return first * second; if (oper == '/') return first / second; return -1; } /*權重計算: 數字權重固定是0,()權重固定是-1; 加減的基礎權重是1 乘除的基礎權重是2 ; ()括號控制附加權重0, (:附加權重+2 ):附加權重-2 [之所以選擇附加權重為2舉例: 2*(2+3)中要先算加法. 加的基礎權重1+附加權重2得到3;乘的基礎權重2+附加權重0得到2.所以會先算加法] 加減乘除的最終權重為 他的基礎權重+當前附加權重*/ //values公式串, pris公式串對應的權重串[in out] int calPri(const vector<char>& values, vector<int>& pris) { int basePri = 0; //附加權重 for(int i = 0; i < values.size(); ++i) { if (!isOper(values[i])) { pris[i] = 0; } if (values[i] == '(') { basePri+=2; pris[i] = -1; } if (values[i] == ')') { basePri-=2; pris[i] = -1; } if ((values[i] == '+') || (values[i] == '-')) { pris[i] = 1 + basePri; } if ((values[i] == '*') || (values[i] == '/')) { pris[i] = 2 + basePri; } } } //移除公式串和權重串中的括號字元 void removeParentheses(vector<char>& values, vector<int>& pris) { for(int i = values.size(); i >= 0; --i) { if ((values[i] == '(') || (values[i] == ')')) { values.erase(values.begin()+i); pris.erase(pris.begin()+i); } } } /*獲取可以計算的權重符的位置: 如果左邊操作符的權重>= 右邊操作符的權重,那麼左邊操作符的左右資料可以進行計算 如果左邊操作符的權重< 右邊操作符的權重,那麼需要右邊操作符和它的右邊操作符進行比較。 */ int getCalPos(const vector<int>& pris) { //pris[0]是左數字, pris[1]是操作符 pris[2]是右數字 for(int i = 1; i < pris.size(); i+=2) { if(i+2 < pris.size()) { if (pris[i] >= pris[i+2]) //如果左操作符的權重 >= 右操作符的權重,那麼此左操作符可以計算 { return i; } } } return pris.size() - 2; } void calResult(vector<char>& values, vector<int>& pris) { while(values.size() != 1) { //獲取可以計算的操作符的位置,並進行左右數字和操作符的計算 int pos = getCalPos(pris); int result = realCal(values[pos-1], values[pos], values[pos+1]); //當左數字,操作符,右數字計算完後,刪掉操作符和右陣列的位置,左數字的位置改成計算結果。然後繼續計算。 //舉例2*3+4 計算2*3得出6,刪除*這個位置,3這個位置,2這個位置改成6.這樣公式變成6+4.下次迴圈繼續計算6+4 values.erase(values.begin()+pos+1); pris.erase(pris.begin()+pos+1); values.erase(values.begin()+pos); pris.erase(pris.begin()+pos); values[pos-1] = result;; prtVecs(values); } } int main() { //原始字串 char data[]="2*3+(2*(5+6)*3)/2+4*6"; vector<char> values; myCopy(values, data); cout << "origin:"; prtVecs(values); // prtVecs(values, pris); //計算原始字串的權重 vector<int> pris(values.size(),0); calPri(values, pris); //原始字串去掉括號 removeParentheses(values,pris);//把括號去掉 // prtVecs(values, pris); calResult(values, pris); cout << "result:"; prtVecs(values); }