我用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
|