您的位置:首页 > 其它

四则运算表达式求值

2016-01-20 18:36 381 查看
1. 算法描述:

输入一个中缀表达式,包括+,-,*,/,(,) 的四则运算,求其计算结果.

2. 算法思想:

将中序转换成后序;

利用栈的数据结构和后序表达式求值

#include<iostream>
#include<stack>
#include<string>
#include<map>
#include<sstream>
#include<fstream>
using namespace std;

const string infixToPostfix(const string &infix);
void ifGetdigit(char ch, string &postfix);
void ifGetOperator(char ch, string &postfix, stack<char> &Stack_operators);
void isLeftParenthesis(char ch, stack<char> &Stack_operators);
void isRightParenthesis(string &postfix, stack<char> &Stack_operators);
void isArithmeticOperator(char ch, string &postfix, stack<char> &Stack_operators);
bool lastOneIsRightParenthesis(const string &postfix);
void appendOperatorsLeft(string &postfix, stack<char> Stack_operators);
double calculate(const string &postfix);
char putOperandsIntoStack(istringstream &in, stack<double> &operand);
void singleOperate(char ch, stack<double> &operand);

int main(void) {

string expression;
ifstream fin("in.txt");

if (!fin.is_open()) {
exit(EXIT_FAILURE);
}

while (!fin.eof()) {
getline(fin, expression);
cout << expression << " = " ;
cout << calculate(infixToPostfix(expression)) << endl;
}

system("pause");
return 0;
}

const string infixToPostfix(const string &infix) {

istringstream fin(infix);
stack<char> Stack_operators;
string postfix;
char ch;

while (!fin.eof()) {
if (fin >> ch) {
if (isdigit(ch) || ch == '.')
ifGetdigit(ch, postfix);
else {
ifGetOperator(ch, postfix, Stack_operators);
}
}
}
appendOperatorsLeft(postfix, Stack_operators);

return postfix;
}

void ifGetdigit(char ch, string &postfix) {
postfix.push_back(ch);
}

void ifGetOperator(char ch, string &postfix, stack<char> &Stack_operators) {
switch (ch) {
case '(':   isLeftParenthesis(ch, Stack_operators);             break;
case ')':   isRightParenthesis(postfix, Stack_operators);       break;
default :   isArithmeticOperator(ch, postfix, Stack_operators); break;
}
}

void isLeftParenthesis(char ch, stack<char> &Stack_operators){
Stack_operators.push(ch);
}

void isRightParenthesis(string &postfix, stack<char> &Stack_operators){
while (!(Stack_operators.top() == '(')) {
postfix.push_back('#');
postfix.push_back(Stack_operators.top());
Stack_operators.pop();
}
postfix.push_back('@');
Stack_operators.pop();
}

void isArithmeticOperator(char ch, string &postfix, stack<char> &Stack_operators){
map<char, int> priority;
priority['+'] = 0;
priority['-'] = 0;
priority['*'] = 1;
priority['/'] = 1;

if (lastOneIsRightParenthesis(postfix))
postfix.erase(postfix.end() - 1);
else
postfix.push_back('#');
while (!Stack_operators.empty() && (Stack_operators.top() != '(')) {
if (priority[ch] <= priority[Stack_operators.top()]) {
postfix.push_back(Stack_operators.top());
Stack_operators.pop();
}
else {
break;
}
}
Stack_operators.push(ch);
}

bool lastOneIsRightParenthesis(const string &postfix) {
return *postfix.crbegin() == '@';
}

void appendOperatorsLeft(string &postfix, stack<char> Stack_operators) {
if (lastOneIsRightParenthesis(postfix))
postfix.erase(postfix.end() - 1);
else
postfix.push_back('#');
while (!Stack_operators.empty()) {
postfix.push_back(Stack_operators.top());
Stack_operators.pop();
}
}

double calculate(const string &postfix) {
istringstream in(postfix);
char operators;
stack<double>  operand;

while (!in.eof()) {
operators = putOperandsIntoStack(in,operand);
if (in.eof())
break;
singleOperate(operators,operand);
}
return operand.top();
}

char putOperandsIntoStack(istringstream &in,stack<double> &operand) {
char ch;
string doublestr;
while ((in >> ch)) {
if (isdigit(ch) || ch == '.') {
while (ch != '#') {
doublestr.push_back(ch);
in >> ch;
}
operand.push(stod(doublestr));
doublestr.clear();
}
else if (ch != '#') {
break;
}
}
return ch;
}

void singleOperate(char ch, stack<double> &operand) {
double second = operand.top();
operand.pop();
double first = operand.top();
operand.pop();
switch (ch) {
case '+':   operand.push(first + second);   break;
case '-':   operand.push(first - second);   break;
case '*':   operand.push(first * second);   break;
case '/':   operand.push(first / second);   break;
default:                                    break;
}
}




注:看了《代码整洁之道》后,第一次这样编程,希望各位朋友指出其中不足,大家共同进步!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: