|
发表于 2017-12-22 00:21:03
|
显示全部楼层
我用C++写了一个,仅供参考
注:程序没有错误处理,增加错误处理会让代码变得更长,如果没有必要,就不加了
main.cpp
- #include <iostream>
- #include <string>
- #include "expression.h"
- int main(void)
- {
- //Expression e("((12 + 1) * 3 - 1) - (12 - 1) * (3 + 3)");
- Expression e;
- std::string expression;
- while(std::getline(std::cin, expression))
- {
- e.SetExpression(expression.c_str());
- e.PrintInfixExpression();
- e.PrintPostfixExpression();
- std::cout << e.Calculate() << std::endl;
- }
- return 0;
- }
复制代码
expression.cpp
- #include "expression.h"
- #include <iostream>
- #include <stack>
- Expression::Expression()
- {
- }
- Expression::Expression(const char *expression)
- {
- SetExpression(expression);
- }
- void Expression::SetExpression(const char *expression)
- {
- infixExpression.clear();
- postfixExpression.clear();
- ParseString(infixExpression, expression);
- InfixExpressionToPostfixExpression(postfixExpression, infixExpression);
- }
- void Expression::ParseString(std::vector<Element> &expr, const char *expression)
- {
- Element element;
- const char *index = expression;
- while(index = GetElement(element, index))
- expr.push_back(element);
- }
- const char *Expression::GetElement(Element &element, const char *str)
- {
- if(*str == '\0')
- return NULL;
- if(('0' <= *str) && (*str <= '9'))
- {
- //数字
- element.elementType = Element::NUMBER;
- element.data.num = element.data.num = 0;
- std::vector<char> vchar;
- while(1)
- {
- if(!(('0' <= *str) && (*str <= '9')))
- if(*str != '.')
- break;
- vchar.push_back(*str);
- str++;
- }
- bool is_integer = true;
- double scale = 10;
- std::vector<char>::iterator iter;
- for(iter = vchar.begin(); iter != vchar.end(); iter++)
- {
- if(is_integer)
- {
- if(*iter == '.')
- {
- is_integer = false;
- continue;
- }
- element.data.num = element.data.num * 10 + (*iter - '0');
- }
- else
- {
- element.data.num += (*iter - '0') / scale;
- scale *= 10;
- }
- }
- }
- else
- {
- //符号
-
- if(*str == ' ')
- {
- str = GetElement(element, ++str);
- return str;
- }
-
- element.elementType = Element::SYMBOL;
- element.data.ch = *str;
-
- str++;
- }
- return str;
- }
- void Expression::PrintInfixExpression(void)
- {
- PrintExpression(infixExpression);
- }
- void Expression::PrintPostfixExpression(void)
- {
- PrintExpression(postfixExpression);
- }
- void Expression::PrintExpression(std::vector<Element> &expression)
- {
- for(std::vector<Element>::iterator iter = expression.begin(); iter != expression.end(); iter++)
- {
- Element element = *iter;
- if(element.elementType == Element::SYMBOL)
- {
- std::cout << element.data.ch;
- }
- else
- {
- std::cout << element.data.num;
- }
- std::cout << ' ';
- }
- std::cout << std::endl;
- }
- bool Expression::InfixExpressionToPostfixExpression(std::vector<Element> &postfixExpression, const std::vector<Element> &infixExpression)
- {
- std::stack<Element> stack;
- for(std::vector<Element>::const_iterator iter = infixExpression.begin(); iter != infixExpression.end(); iter++)
- {
- Element element = *iter;
- if(element.elementType == Element::NUMBER)
- {
- postfixExpression.push_back(element);
- }
- else
- {
- if(stack.empty())
- {
- stack.push(element);
- continue;
- }
- if(element.data.ch == '(')
- {
- stack.push(element);
- continue;
- }
- if(element.data.ch == ')')
- {
- PopStack(postfixExpression, stack);
- continue;
- }
- if(GetPriority(element.data.ch) >= GetPriority(stack.top().data.ch))
- {
- stack.push(element);
- }
- else
- {
- PopStack(postfixExpression, stack);
- stack.push(element);
- }
- }
- }
- while(!stack.empty())
- {
- Element elementTmp = stack.top();
- stack.pop();
- postfixExpression.push_back(elementTmp);
- }
- return true;
- }
- inline unsigned int Expression::GetPriority(char ch)
- {
- switch(ch)
- {
- case '(':
- case ')':
- return 0;
- case '+':
- case '-':
- return 1;
- case '*':
- case '/':
- return 2;
- default:
- return -1;
- }
- }
- void Expression::PopStack(std::vector<Element> &postfixExpression, std::stack<Element> &stack)
- {
- while(!stack.empty())
- {
- Element element = stack.top();
- stack.pop();
- if(element.data.ch != '(')
- postfixExpression.push_back(element);
- else
- break;
- }
- }
- double Expression::Calculate(void)
- {
- std::stack<Element> stack;
- for(std::vector<Element>::const_iterator iter = postfixExpression.begin(); iter != postfixExpression.end(); iter++)
- {
- Element element = *iter;
- if(element.elementType == Element::NUMBER)
- {
- stack.push(element);
- }
- else
- {
- double num1, num2;
- Element elementTmp;
- elementTmp = stack.top();
- stack.pop();
- num1 = elementTmp.data.num;
- elementTmp = stack.top();
- stack.pop();
- num2 = elementTmp.data.num;
- switch(element.data.ch)
- {
- case '+':
- elementTmp.data.num = num2 + num1;
- stack.push(elementTmp);
- break;
- case '-':
- elementTmp.data.num = num2 - num1;
- stack.push(elementTmp);
- break;
- case '*':
- elementTmp.data.num = num2 * num1;
- stack.push(elementTmp);
- break;
- case '/':
- if(num1 == 0)
- throw "除数为0";
- elementTmp.data.num = num2 / num1;
- stack.push(elementTmp);
- break;
- }
- }
- }
- Element elementTmp = stack.top();
- stack.pop();
- return elementTmp.data.num;
- }
复制代码
expression.h
- #ifndef _EXPRESSION_H_
- #define _EXPRESSION_H_
- #include <vector>
- #include <stack>
- class Expression
- {
- public:
- Expression();
- Expression(const char * expression);
- void SetExpression(const char *expression);
- double Calculate(void);
- void PrintInfixExpression(void);
- void PrintPostfixExpression(void);
- private:
- typedef struct
- {
- enum { NUMBER, SYMBOL } elementType;
- union { char ch; double num; } data;
- } Element;
- std::vector<Element> infixExpression;
- std::vector<Element> postfixExpression;
- void ParseString(std::vector<Element>& expr, const char *expression);
- const char *GetElement(Element &element, const char *str);
-
- inline unsigned int GetPriority(char ch);
- void PopStack(std::vector<Element> &postfixExpression, std::stack<Element> &stack);
- bool InfixExpressionToPostfixExpression(std::vector<Element> &postfixExpression, const std::vector<Element> &infixExpression);
- void PrintExpression(std::vector<Element> &expression);
- };
- #endif
复制代码
|
|