代碼。。。。
/*
參考:http://www.nowamagic.net/librarys/veda/detail/2306
http://blog.csdn.net/geekcoder/article/details/6829386
http://blog.csdn.net/mvpsendoh/article/details/6440559
雖說是參考,可是受作者思路影響,裏面相同的地方還是太多了= =。
*/
#include <iostream>
#include <stack>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#define ENDCHAR '#'
using namespace std;
//中綴轉後綴部分
int isOperator(char c)
{
switch(c)
{
case '+':
case '-':
case '*':
case '/':
case '%':
case '^':
return 1;
default:
return 0;
}
}
int priority(char c)
{
switch(c)
{
case ENDCHAR:
case '(':
return 0;
case '+':
case '-':
return 1;
case '%'://坑爹了。。學了這麼久,今天終於知道求模跟乘除是同一優先級
case '*':
case '/':
return 2;
case '^':
return 4;
default:
cout << "Invalid Operator!: '" << c << "'" << endl;
exit(1);
}
}
void popAll(stack<char>&stk, char postfix[], int postIndex)
{
while(stk.size() != 0)
{
postfix[postIndex++] = stk.top();
stk.pop();
}
postfix[--postIndex] = '\0'; //在'#'處插入結束符
}
void infix2postfix(char infix[], char postfix[])
{
int inIndex = 0, postIndex = 0;
stack<char>operators;
operators.push(ENDCHAR);//壓入ENDCHAR避免後面操作到空棧而出錯
while(infix[inIndex])
{
if(isdigit(infix[inIndex]) || infix[inIndex] == '.') //數字直接輸出到postfix中
{
postfix[postIndex++] = infix[inIndex];
}
else if(infix[inIndex] == '(')
{
//'(' 入棧
operators.push(infix[inIndex]);
}
else if(infix[inIndex] == ')') //括號與運算符分開處理
{
/*
噹噹前符號爲')'
則依次彈出棧中符號直至遇到'('
*/
while(operators.top() != '(')
{
postfix[postIndex++] = operators.top();
operators.pop();
}
operators.pop(); //彈出'('
}
else if(isOperator(infix[inIndex]))
{
/*
將當前操作符與棧頂操作符比較
若小於等於棧頂操作符
則將棧頂操作符彈出直至當前操作符大於棧頂操作符
最後將當前操作符入棧
*/
postfix[postIndex++] = ' '; //隔開操作數
while(priority(infix[inIndex]) <= priority(operators.top()))
{
postfix[postIndex++] = operators.top();
operators.pop();
}
operators.push(infix[inIndex]);
}
++inIndex;
}
popAll(operators, postfix, postIndex);//全部操作符出棧
}
//表達式求值部分
double calc(double num1, double num2, char op)
{
switch(op)
{
case '+':return num1 + num2;
case '-':return num1 - num2;
case '*':return num1 * num2;
case '/':return num1 / num2;
case '%':return fmod(num1, num2);
case '^':return pow(num1, num2);
default:
exit(1);
}
}
double readNumber(char **string)
{
double intNumber = 0;
double floatNumber = 0;
int times = 1;
while(isdigit(**string))
{
intNumber = intNumber * 10 + **string - '0';
++*string;
}
if(**string == '.')
{
++*string;
while(isdigit(**string))
{
floatNumber = floatNumber + (**string - '0') * pow(0.1, times);
++*string;
}
}
return intNumber + floatNumber;
}
double calcPostfix(char postfix[])
{
double num1, num2;
stack<double>numbers;
while(*postfix)
{
if(isdigit(*postfix))
{
numbers.push(readNumber(&postfix));//讀取數字
}
else if(isOperator(*postfix))
{
/*
取得2操作數
執行當前運算並將結果入棧
*/
num2 = numbers.top();
numbers.pop();
num1 = numbers.top();
numbers.pop();
numbers.push(calc(num1, num2, *postfix++));
}
else if(isspace(*postfix))
{
++postfix; //跳過空格
}
}
return numbers.top();
}
int main()
{
char infix[100] = "", postfix[100] = "";
while(1)
{
cout << "Input:";
cin >> infix;
infix2postfix(infix, postfix);
cout << "Postfix:" << postfix << endl;
cout << "Value:" << calcPostfix(postfix) << endl;
}
return 0;
}
運行截圖。。。
總結。。。
終於知道%*/是同一優先級了。。。。