//程序说明:算法封装于一个类里面,计算方法为先将中缀表达式转化为后缀表达式,然后计算其值!该程序在VS2005里面编译通过。
//参考《数据结构实用教程(C/C++描述)》 清华大学出版社 徐孝凯
//类头文件Experssion.h
#pragma once
class Experssion
{
public: //构造函数
Experssion(void);
Experssion(char* strExper); //用中缀表达式构造类
public: //析构函数
~Experssion(void);
public: //公共方法
void SetString(char* strExper); //设置中缀表达式
char* GetMidString(); //返回中缀表达式
char* GetEndString(); //返回后缀表达式
bool Transforms(); //将中缀表达式转换为后缀表达式
double ComputeMid(); //计算中缀表达式
double ComputeEnd(); //计算后缀表达式
private: //内部变量
char* m_strMidExperssion; //中缀表达式
char* m_strEndExperssion; //后缀表达式
};
//实现文件Experssion.cpp
#include "StdAfx.h"
#include "Experssion.h"
#include <stack>
#include <strstream>
#include <ctype.h>
using namespace std;
Experssion::Experssion(void)
{
this->m_strEndExperssion = NULL;
this->m_strMidExperssion = NULL;
}
Experssion::Experssion(char *strExper)
{
this->m_strEndExperssion = NULL;
this->m_strMidExperssion = strExper;
}
Experssion::~Experssion(void)
{
}
void Experssion::SetString(char* strExper)
{
this->m_strMidExperssion = strExper;
int i = strlen(this->m_strMidExperssion);
this->m_strEndExperssion = new char[i];
}
char* Experssion::GetMidString()
{
return this->m_strMidExperssion;
}
char* Experssion::GetEndString()
{
return this->m_strEndExperssion;
}
//判断运算符的优先级
int Precedence(char op)
{
switch(op)
{
case '+':
case '-':
return 1; //定义加减运算符的优先级为1
case '*':
case '/':
return 2; //定义乘除运算符的优先级为2
default:
return 0; //其余优先级为0
}
}
bool Experssion::Transforms()
{
if(this->m_strMidExperssion == NULL)
{
return false;
}
stack<char> stk;
stk.push('@');
int i = 0,j = 0;
char w;
char ch = this->m_strMidExperssion[i];
while(ch != '@')
{
switch(ch)
{
case ' ':
ch = this->m_strMidExperssion[++i];
break;
case '(':
stk.push(ch);
ch = this->m_strMidExperssion[++i];
break;
case ')':
while(stk.top() != '(')
{
this->m_strEndExperssion[j++] = stk.top();
stk.pop();
}
stk.pop();
ch = this->m_strMidExperssion[++i];
break;
case '+':
case '-':
case '*':
case '/':
w = stk.top();
while(Precedence(w) > Precedence(ch))
{
this->m_strEndExperssion[j++] = w;
stk.pop();
w = stk.top();
}
stk.push(ch);
ch = this->m_strMidExperssion[++i];
break;
default:
while(isdigit(ch)||ch=='.')
{
this->m_strEndExperssion[j++] = ch;
ch = this->m_strMidExperssion[++i];
}
this->m_strEndExperssion[j++] = ' ';
}
}
ch = stk.top();
stk.pop();
while(ch != '@')
{
if(ch == '(')
{
return false;
}
else
{
this->m_strEndExperssion[j++] = ch;
ch = stk.top();
stk.pop();
}
}
this->m_strEndExperssion[j++] = '@';
this->m_strEndExperssion[j++] = ' ';
return true;
}
double Experssion::ComputeEnd()
{
if(this->m_strEndExperssion == NULL)
{
return 0;
}
char ch;
double x;
stack<double> stk;
istrstream ins(this->m_strEndExperssion);
ins>>ch;
while(ch != '@')
{
switch(ch)
{
case '+':
x = stk.top();
stk.pop();
x += stk.top();
stk.pop();
break;
case '-':
x = stk.top();
stk.pop();
x = stk.top() - x;
stk.pop();
break;
case '*':
x = stk.top();
stk.pop();;
x *= stk.top();
stk.pop();
break;
case '/':
x = stk.top();
if(x == 0)
{
return 0;
}
stk.pop();
x = stk.top()/x;
stk.pop();
break;
default:
ins.putback(ch);
ins>>x;
}
stk.push(x);
ins>>ch;
}
if(!stk.empty())
{
x = stk.top();
stk.pop();
if(!stk.empty())
{
return 0;
}
return x;
}
else
{
return 0;
}
}
double Experssion::ComputeMid()
{
if(this->Transforms())
{
return this->ComputeEnd();
}
else
{
return 0;
}
}
//应用举例
// Express.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "Experssion.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Experssion exper;
exper.SetString("(5+3.6*(3.4+5.2))*5@");
cout<<exper.ComputeMid()<<endl;
getchar();
return 0;
}