@zsh-o
2018-08-26T15:00:37.000000Z
字数 6824
阅读 1295
算法
如题,写了两个,一个是用python正则表达式,另一个C++用后缀表达式
Python正则表达式思路是用正则表达式搜索所有的可计算的表达式,用结果替换,然后迭代计算得到最终结果
#!/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2018/3/21 9:24# Author : zsh_oimport redef cal_mul(matched):sa = matched.group(1)sb = matched.group(2)if len(sa)>1 and sa[0] == '0' and sa[1] == '0':a = -float(sa)else:a = float(sa)if len(sb)>1 and sb[0] == '0' and sb[1] == '0':b = -float(sb)else:b = float(sb)c = a * bif c < 0:return '00' + str(-c)else:return str(c)def cal_div(matched):sa = matched.group(1)sb = matched.group(2)if len(sa) > 1 and sa[0] == '0' and sa[1] == '0':a = -float(sa)else:a = float(sa)if len(sb) > 1 and sb[0] == '0' and sb[1] == '0':b = -float(sb)else:b = float(sb)c = a / bif c < 0:return '00' + str(-c)else:return str(c)def cal_add(matched):sa = matched.group(1)sb = matched.group(2)if len(sa) > 1 and sa[0] == '0' and sa[1] == '0':a = -float(sa)else:a = float(sa)if len(sb) > 1 and sb[0] == '0' and sb[1] == '0':b = -float(sb)else:b = float(sb)c = a + bif c < 0:return '00' + str(-c)else:return str(c)def cal_sub(matched):sa = matched.group(1)if sa == '':sa = '0'sb = matched.group(2)if len(sa) > 1 and sa[0] == '0' and sa[1] == '0':a = -float(sa)else:a = float(sa)if len(sb) > 1 and sb[0] == '0' and sb[1] == '0':b = -float(sb)else:b = float(sb)c = a - bif c < 0:return '00' + str(-c)else:return str(c)def cal_bracket(matched):bracket_s = matched.group(1)p = bracket_s## 先算除法st = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\/([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\/([0-9]+[.]{0,1}[0-9]*)', cal_div, p, count=1)st = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\*([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\*([0-9]+[.]{0,1}[0-9]*)', cal_mul, p, count=1)## 先算负的,再算正的,防止开头是负号的情况st = []while st is not None:st = re.search('([0-9]*[.]{0,1}[0-9]*)\-([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]*[.]{0,1}[0-9]*)\-([0-9]+[.]{0,1}[0-9]*)', cal_sub, p, count=1)st = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\+([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\+([0-9]+[.]{0,1}[0-9]*)', cal_add, p, count=1)st = p[1:-1]return sts = '1-2*((60-30+(9-2*5/3+7/3*99/4*2998+10*2998+10*568/14))-(-4*3)/(16-3*2))'# s = '1-2'p = sst = []while st is not None:st = re.search('(\([^\(\)]+\))', p)p = re.sub('(\([^\(\)]+\))', cal_bracket, p)def cal_final(final_s):p = final_sst = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\/([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\/([0-9]+[.]{0,1}[0-9]+)', cal_div, p, count=1)st = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\*([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\*([0-9]+[.]{0,1}[0-9]*)', cal_mul, p, count=1)## 先算负的,再算正的,防止开头是负号的情况st = []while st is not None:st = re.search('([0-9]*[.]{0,1}[0-9]*)\-([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]*[.]{0,1}[0-9]*)\-([0-9]+[.]{0,1}[0-9]*)', cal_sub, p, count=1)st = []while st is not None:st = re.search('([0-9]+[.]{0,1}[0-9]*)\+([0-9]+[.]{0,1}[0-9]*)', p)p = re.sub('([0-9]+[.]{0,1}[0-9]*)\+([0-9]+[.]{0,1}[0-9]*)', cal_add, p, count=1)a = float(p)if len(p) > 1 and p[0] == '0' and p[1] == '0':a = -areturn aprint(cal_final(p))print(eval(s))
C++后缀表达式支持小数
//// Created by zsh96 on 2018/4/20.///*** 计算字符串的值,后缀表达式* */#include <iostream>#include <cstring>#include <map>#include <vector>#include <stack>using namespace std;struct Item{bool isNumber;char symbol;double value;Item(double value):isNumber(true),value(value){}Item(char symbol):isNumber(false),symbol(symbol){}};class Operator{public:char label;explicit Operator(char label): label(label){}virtual double calculate(double a, double b)=0;};class Add:public Operator{public:Add() : Operator('+') {}double calculate(double a, double b) override {return a + b;}};class Sub:public Operator{public:Sub() : Operator('-') {}double calculate(double a, double b) override {return a - b;}};class Mul:public Operator{public:Mul() : Operator('*') {}double calculate(double a, double b) override {return a * b;}};class Div:public Operator{public:Div() : Operator('/') {}double calculate(double a, double b) override {return a / b;}};class OperatorManager{public:map<char, Operator *> operatorList;map<char, int> operatorLevel;OperatorManager(){operatorList['+'] = new Add();operatorList['-'] = new Sub();operatorList['*'] = new Mul();operatorList['/'] = new Div();operatorLevel['+'] = 1;operatorLevel['-'] = 1;operatorLevel['*'] = 2;operatorLevel['/'] = 2;operatorLevel['('] = 3;operatorLevel[')'] = 3;}double calculate(char operc, double a, double b){return operatorList[operc]->calculate(a, b);}};bool isNumber(char c){return c>='0' && c<='9';}double e10(int n){double res = 10;while(--n){res *= 10;}return res;}OperatorManager operatorManager;int main(){cout<<"Inputs: ";string line;getline(cin, line);vector<Item *> Items;double sum = 0;bool isfloat = false;bool isnegative = false;char LastC = '~';int floatNum = 0;bool lastisNumber = (line[0]!='(');for(int i=0; i<line.size(); i++){char c = line[i];if(!isNumber(c)){if(c == '-' && (LastC == '(' || LastC == '~')){Items.push_back(new Item(0.));}if(c=='.'){if(isfloat){cout<<"Error"<<endl;}else{isfloat = true;}lastisNumber = true;}else{if(c == ' '){continue;}if(lastisNumber){Items.push_back(new Item(sum));}Items.push_back(new Item(c));sum = 0;floatNum = 0;isfloat = false;lastisNumber = false;LastC = c;}}else {double t = c - '0';if (!isfloat) {sum = sum * 10 + t;} else {floatNum++;sum = sum + (c - '0') / e10(floatNum);}lastisNumber = true;if (i == line.size() - 1) {Items.push_back(new Item(sum));}LastC = c;}}// 转为后缀表达式vector<Item *> postfix;stack<Item *> temp_stack;for(int i=0; i<Items.size(); i++){Item *item = Items[i];if(item->isNumber){postfix.push_back(item);}else{if(item->symbol=='('){temp_stack.push(item);}else if(item->symbol==')'){Item *temp = temp_stack.top();while(!temp_stack.empty() && temp->symbol!='('){postfix.push_back(temp);temp_stack.pop();if(!temp_stack.empty())temp = temp_stack.top();}temp_stack.pop();}else{if(!temp_stack.empty()){Item *temp = temp_stack.top();while(!temp_stack.empty() && operatorManager.operatorLevel[temp->symbol]>=operatorManager.operatorLevel[item->symbol] && temp->symbol!='('){postfix.push_back(temp);temp_stack.pop();if(!temp_stack.empty())temp = temp_stack.top();}}temp_stack.push(item);}}}while(!temp_stack.empty()){postfix.push_back(temp_stack.top());temp_stack.pop();}// ------cout<<"Items: ";for(int i=0; i<Items.size(); i++){Item *item = Items[i];if(item->isNumber){cout<<item->value;}else{cout<<item->symbol;}}cout<<endl;cout<<"Postfix Expression: ";for(int i=0; i<postfix.size(); i++){Item *item = postfix[i];if(item->isNumber){cout<<item->value;}else{cout<<item->symbol;}}cout<<endl;// 计算for(int i=0; i<postfix.size(); i++){Item *item = postfix[i];if(item->isNumber){temp_stack.push(item);}else{Item *b = temp_stack.top();temp_stack.pop();Item *a = temp_stack.top();temp_stack.pop();temp_stack.push(new Item(operatorManager.calculate(item->symbol, a->value, b->value)));}}// -----Item *result = temp_stack.top();printf("Result: %.3lf\n", result->value);cin.get();}
Inputs: 1-2*((60-30+(9-2*5/3+7/3*99/4*2998+10*2998+10*568/14))-(-4*3)/(16-3*2))Items: 1-2*((60-30+(9-2*5/3+7/3*99/4*2998+10*2998+10*568/14))-(0-4*3)/(16-3*2))Postfix Expression: 126030-925*3/-73/99*4/2998*+102998*+10568*14/++043*-1632*-/-*-Result: -407113.162Inputs: 1.4*(2-4.5/5) - (-3.2+5)Items: 1.4*(2-4.5/5)-(0-3.2+5)Postfix Expression: 1.424.55/-*03.2-5+-Result: -0.260