计算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); }