@zsh-o
2018-08-26T23:00:37.000000Z
字数 6824
阅读 1067
算法
如题,写了两个,一个是用python
正则表达式,另一个C++
用后缀表达式
Python
正则表达式思路是用正则表达式搜索所有的可计算的表达式,用结果替换,然后迭代计算得到最终结果
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2018/3/21 9:24
# Author : zsh_o
import re
def 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 * b
if 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 / b
if 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 + b
if 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 - b
if 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 st
s = '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 = s
st = []
while st is not None:
st = re.search('(\([^\(\)]+\))', p)
p = re.sub('(\([^\(\)]+\))', cal_bracket, p)
def cal_final(final_s):
p = final_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)
a = float(p)
if len(p) > 1 and p[0] == '0' and p[1] == '0':
a = -a
return a
print(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.162
Inputs: 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