计算算术表达式值的源程序

//程序说明:算法封装于一个类里面,计算方法为先将中缀表达式转化为后缀表达式,然后计算其值!该程序在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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值