思路:首先利用棧A把四則運算的字符串從中序表達式轉換成後序表達式;然後對後序表達式,如果是數字則保存到另一個棧B中,如果是運算符(+,-,*,/)就從棧B中依次獲取棧頂兩個操作數進行運算,運算結果再壓棧B,如此反覆,最終棧B中最後的值就是運算結果。
#define MAX_LENGTH 500
class Data
{
public:
double num;
char op;
};
class FourArithmeticOP
{
private:
Stack<double> numStack; //進行四則運算時,保存後序表達式中的操作數
Stack<char> opStack; //保存中序表達式轉換成後序表達式過程中的操作符
int InStackPriority(char op); //進入棧內後的優先級
int NormalPriority(char op); //普通表達式中的優先級
public:
Data post[MAX_LENGTH]; //保存後序表達式
int postLength; //後序表達式數組的實際長度
void InorderToPostorder(char *cExp); //把中序表達式轉換成後序表達式
double Calculate(); //進行四則運算
};
//對四則運算符,棧內優先級提升,'('的棧內優先級應該比所有的操作符都小,')'的棧內優先級應該最大
//+-的優先級一致,*/的優先級一致
int FourArithmeticOP::InStackPriority(char op)
{
int priority;
switch (op)
{
case '+' : priority = 3;
break;
case '-' : priority = 3;
break;
case '*' : priority = 5;
break;
case '/' : priority = 5;
break;
case '(' : priority = 1;
break;
case ')' : priority = 10;
break;
default: priority = 0;
break;
}
return priority;
}
int FourArithmeticOP::NormalPriority(char op)
{
int priority;
switch (op)
{
case '+' : priority = 2;
break;
case '-' : priority = 2;
break;
case '*' : priority = 4;
break;
case '/' : priority = 4;
break;
case '(' : priority = 10;
break;
case ')' : priority = 1;
break;
default: priority = 0;
break;
}
return priority;
}
void FourArithmeticOP::InorderToPostorder(char *cExp)
{
char num[10];
//把字符串中的數字和操作符(+-*/)放入後序表達式
opStack.makeEmpty();
//加入一個優先級最低的特殊字符,使opStack不爲空
opStack.push('&');
int index = 0;
postLength = 0;
while (cExp[index] != '\0')
{
if (cExp[index] == '+' || cExp[index] == '-' || cExp[index] == '*' || cExp[index] == '/' || cExp[index] == '(')
{
//優先級高於當前操作符的棧內操作符出棧
while (NormalPriority(cExp[index]) < InStackPriority(opStack.getTop()))
{
post[postLength++].op = opStack.pop();
}
opStack.push(cExp[index]);
}
else if (cExp[index] == ')')
{
//一直退棧到'('
while (opStack.getTop() != '(')
{
post[postLength++].op = opStack.pop();
}
// '(' 出棧
opStack.pop();
}
else if (cExp[index] >= '0' && cExp[index] <= '9')
{
//數字
int j = 0;
memset(num, 0, 10);
while (cExp[index] >= '0' && cExp[index] <= '9')
{
num[j++] = cExp[index++];
}
index--;
post[postLength].num = atof(num);
post[postLength].op = '&';
postLength++;
}
else
{
//非法字符,不處理
}
index++;
}
while (opStack.getTop() != '&')
{
post[postLength++].op = opStack.pop();
}
// '&' 出棧
opStack.pop();
}
//根據後序表達式進行四則運算
double FourArithmeticOP::Calculate()
{
double left, right;
numStack.makeEmpty();
for (int i = 0; i < postLength; i++)
{
if (post[i].op == '&')
{
// 數字
numStack.push(post[i].num);
}
else
{
//操作符,取出兩個數字進行運算
right = numStack.pop();
left = numStack.pop();
switch (post[i].op)
{
case '+' : numStack.push(left + right);
break;
case '-' : numStack.push(left - right);
break;
case '*' : numStack.push(left * right);
break;
case '/' : numStack.push(left / right);
break;
}
}
}
return numStack.pop();
}
以上內容轉載自 http://blog.163.com/wmk_2000_ren/blog/static/138846192201031211285589/
以下爲本人的代碼,其中計算優先級的部分借用了上述的代碼。
所有操作都封裝到了一個類中
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <vector>
#include <list>
#include <stack>
#include <queue>
using namespace std;
typedef struct{
double operand;
char opt;
}PostNode;
class FourArithmeticOP
{
private:
const char NO_OPERATOR = 0x00;
stack< char , list<char> > OpStack;
queue< PostNode , list<PostNode> > PostStr;
stack< double , list<double> > OperandStack;
public:
FourArithmeticOP() {
OpStack.push('#');
}
~FourArithmeticOP() {
}
int IsNumOrDot(char chra);
int IsOperator(char chra);
int NormalPriority(char opt);
int StackPriority(char opt);
int InorderToPost(char *cExp);
void ShowPostStr();
double Calculate();
};
<span style="font-size:18px;">int FourArithmeticOP::IsNumOrDot(char chra)
{
if( (chra >= '0' && chra <= '9') || chra == '.' )
return 1;
return 0;
}
int FourArithmeticOP::IsOperator(char chra)
{
if(chra == '+' || chra == '-' ||
chra == '*' || chra =='/' ||
chra =='(' || chra == ')')
return 1;
return 0;
}
int FourArithmeticOP::NormalPriority(char opt)
{
int priority;
switch (opt)
{
case '+' : priority = 2;
break;
case '-' : priority = 2;
break;
case '*' : priority = 4;
break;
case '/' : priority = 4;
break;
case '(' : priority = 10;
break;
case ')' : priority = 1;
break;
default: priority = 0;
break;
}
return priority;
}
//相同運算符,在棧中優先級更高
int FourArithmeticOP::StackPriority(char opt)
{
int priority;
switch (opt)
{
case '+' : priority = 3;
break;
case '-' : priority = 3;
break;
case '*' : priority = 5;
break;
case '/' : priority = 5;
break;
case '(' : priority = 1;
break;
case ')' : priority = 10;
break;
default: priority = 0;
break;
}
return priority;
}
int FourArithmeticOP::InorderToPost(char *cExp)
{
string NumStr;
// double num;
PostNode node;
int i = 0;
while(i < strlen(cExp)) {
NumStr.clear();
while(IsNumOrDot(cExp[i])) {
NumStr += cExp[i];
i++;
}//get int or float
if(!NumStr.empty()) {
if('.' == NumStr.at(NumStr.length() - 1) ||
'.' == NumStr.at(0))
{
cout << "valid float : " << NumStr << endl;
return 0;
}
node.operand = atof(NumStr.c_str());
node.opt = NO_OPERATOR;
PostStr.push(node);
}
else if(IsOperator(cExp[i])) {
if(')' == cExp[i]) {</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>//遇到 ) 則 一直彈出直到 (
while('(' != OpStack.top()) {
if('#' == OpStack.top()) {
cout << "parenthesis error" << endl;
return 0;
}
//pop out pair parenthesis
node.opt = OpStack.top();
PostStr.push(node);
OpStack.pop();
}
OpStack.pop(); //pop out '('
i++;
continue;
}
while(NormalPriority(cExp[i]) <= StackPriority(OpStack.top()))
{
node.opt = OpStack.top();
PostStr.push(node);
OpStack.pop();
}
OpStack.push(cExp[i]);
i++;
}
else {
cout << "valid operator : " << cExp[i] << endl;
return 0;
}
}
while('#' != OpStack.top()) {
node.opt = OpStack.top();
PostStr.push(node);
OpStack.pop();
}
return 1;
}
double FourArithmeticOP::Calculate()
{
PostNode node;
double operand_1;
double operand_2;
char Operator;
while(!PostStr.empty()) {
Operator = PostStr.front().opt;
//operand
if(NO_OPERATOR == Operator) {
operand_1 = PostStr.front().operand;
OperandStack.push(operand_1);
// Operator = PostStr.front().opt;
}
else {
//handle operator
operand_2 = OperandStack.top();
OperandStack.pop();
operand_1 = OperandStack.top();
OperandStack.pop();
switch(Operator){
case '+' : OperandStack.push(operand_1 + operand_2);
break;
case '-' : OperandStack.push(operand_1 - operand_2);
break;
case '*' : OperandStack.push(operand_1 * operand_2);
break;
case '/' :
if(0 == operand_2) {
cout << "operand_2 = 0 while /" << endl;
return 0;
}
else {
OperandStack.push(operand_1 / operand_2);
}
}
}
PostStr.pop();
}
double res = OperandStack.top();
OperandStack.pop();
return res;
}</span>