http://www.acmerblog.com/infix-to-postfix-6072.html
http://www.nowamagic.net/librarys/veda/detail/2306
代码分为3部分,我知道很丑,可以不看,主要看原理。
1、translator.h
转换函数,先把 中缀表达式表达为后缀表达式
// 把中缀表达式 转换为 后缀表达式
#pragma once
#include <string>
#include <stdio.h>
#include <stack>
using namespace std;
#include "util.h"
string transform(string input)
{
stack<char> operandStack; // 操作符
string rst;
for (int i=0; i < input.length(); i++)
{
if ( isdigit(input[i]) )
{
// 放到结果里
rst.push_back(input[i]);
}
else if(isCommonOperand(input[i]))
{
// 如果operandStack栈为空,不需要考虑优先级
if (operandStack.empty())
{
operandStack.push(input[i]);
}
else
{
// 此处要考虑优先级
int r = getRank(input[i]);
// 与上一个操作符的优先级比较
// 若大,则入栈
if(r > getRank(operandStack.top()))
{
operandStack.push(input[i]);
}
// 若小于上一个的操作符,就要弹出直到operandStack栈为空或当前的操作符ch的优先级大于栈顶的操作符。
// 最后才将当前操作符入栈。
else{
while(!operandStack.empty() && r <= getRank(operandStack.top()))
{
rst.push_back(operandStack.top()); // 存到结果里
operandStack.pop();
}
operandStack.push(input[i]);
}
}
}
// 左括号也要入操作符栈
else if(input[i] == '('){
operandStack.push(input[i]);
}
// 右括号,比较特殊。操作符栈弹出,放到结果里。直至遇到左括号
else if(input[i] == ')'){
char top = operandStack.top();
while(top != '('){
rst.push_back(top);
operandStack.pop();
top = operandStack.top();
}
operandStack.pop(); //把 ( 也要去掉
}
else {
}
}
// 把剩余的操作符也加上
while(!operandStack.empty())
{
rst.push_back(operandStack.top());
operandStack.pop();
}
return rst;
}
2、calcuator.h
计算函数,计算后缀表达式
// 把输入的后缀表达式 进行入栈 出栈 处理,进行真正的计算
#pragma once
#include <string>
#include <stdio.h>
#include <stack>
using namespace std;
#include "util.h"
/*
从左至右扫描表达式,
遇到数字时,将数字压入堆栈,
遇到运算符时,弹出栈顶的两个数,
用运算符对它们做相应的计算(次顶元素 op 栈顶元素),
并将结果入栈;重复上述过程直到表达式最右端,
最后运算得出的值即为表达式的结果。
*/
float calc(string polan)
{
float result;
stack<float> dataStack; // 操作数 临时存储地方
float first = 0.0;
float second = 0.0;
for (int i=0; i < polan.length(); i++)
{
if ( isdigit(polan[i]) )
{
dataStack.push(polan[i] - '0');
}
else if(isCommonOperand(polan[i]))
{
second= dataStack.top(); //重要,因为先出来的是 位于计算式后面的
dataStack.pop();
first = dataStack.top();
dataStack.pop();
float tmp = doCal(first,second,polan[i]);
dataStack.push (tmp);
}
else
{
}
}
result = dataStack.top();
return result;
}
3、util.h
提供公有函数
#pragma once
#include <stdio.h>
#include <stack>
using namespace std;
bool isCommonOperand(char operand)
{
switch (operand)
{
case '+' :
return true;
case '-':
return true;
case '*':
return true;
case '/':
return true;
default:
return false;
}
return false;
}
// 获取操作符C 的优先级
int getRank(char c)
{
switch (c) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return -1;
}
float doCal(float first,float second,char oper)
{
switch (oper) {
case '+':
return first + second;
case '-':
return first - second;
case '*':
return first*second;
case '/':
return first/second;
}
return 0.0;
}
4、main.cpp
客户端,接受输入
#include "translator.h "
#include "calcuator.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
//cout << "hello" <<endl;
// string inputStr = "1+2-3/4+5*6"; //期望输出 12+34/-56*+
// "(1+2)*3" 期望输出 12+3*
cout << "please input your calc input:" <<endl;
while (1)
{
char Buffer[100]; //从客户端接受的输入
cout<<"请输入计算字符串:"<<endl;
string str;
char rechar[200];//接受从服务端返回的结果
if(cin>>str)
{
if (str.find("q") != string::npos)
{
break;
}
string inputStr = str;
string midStr = transform(inputStr);
float result = calc(midStr);
cout<<"结果输出为:"<<endl;
cout << "result=" << result <<endl;
}
}
return 0;
}