表达式的计算(链栈表示)
2009-05-11 13:05
260 查看
注:此代码只能完成简单的加减乘除四则运算,但是不支持单目运算,更复杂的形式留待以后有时间再进一步完善。
#include "LinkedStack.h"
#include <cmath>
class Calculator
{
public:
Calculator()
{
t.MakeEmpty();
t.Push('#'); //栈底放一个'#'
}
void Run(); //执行表达式计算
void Clear(); //清栈
private:
void AddOperand(double value); //操作数进栈
bool Get2Operands(double & left,double & right); //从栈中退出两个操作数
void DoOperator(char op); //形成运算指令,进行计算
int isp(char ch); //判断操作符的栈内优先数
int icp(char ch); //判断操作符的栈外优先数
LinkedStack<double> s; //栈对象定义,用于后缀表达式的计算过程,存储操作数
4000
LinkedStack<char> t; //栈对象定义,用于中缀表达式转后续表达式的过程,存储操作符
};
//读字符串并求一个后缀表达式的值,以字符'#'结束
void Calculator::Run()
{
char ch,ch1,op;
double newoperand;
cin>>ch;
while(1)
{
if(isdigit(ch)) //是操作数
{
//cout<<ch;
cin.putback(ch); //将字符放回输入流
cin>>newoperand; //重新读取操作数
AddOperand(newoperand); //将操作数放入栈中
cin>>ch; //读取下一扫描项
}
else
{
t.GetTop(ch1); //取栈顶操作符ch1
if (isp(ch1)<icp(ch)) //新输入操作符优先级高
{
t.Push(ch); //进栈
cin>>ch; //读取下一扫描项
}
else if (isp(ch1)>icp(ch)) //新输入操作符优先级低
{
t.Pop(op); //退栈
switch(op)
{
case '+':
case '-':
case '*':
case '/':
DoOperator(op); //是操作符,执行计算
break;
}
}
else //输入操作符优先级等于栈顶优先级
{
if(ch == '#')
break;
t.Pop(op);
if(op == '(')
cin>>ch;
}
}
}
assert(!s.IsEmpty());
double temp;
s.Pop(temp);
cout<<"The result is:"<<temp<<endl;
}
//清栈
void Calculator::Clear()
{
s.MakeEmpty();
}
//取两个操作数,根据操作符op形成运算指令并计算
void Calculator::DoOperator(char op)
{
double left,right;
bool result;
result = Get2Operands(left,right);
if(result == true)
{
switch(op)
{
case '+':
s.Push(left+right);
break;
case '-':
s.Push(left-right);
break;
case '*':
s.Push(left*right);
break;
case '/':
if(right == 0.0)
{
cerr<<"Divided by 0!"<<endl;
Clear();
exit(0);
}
else
s.Push(left/right);
break;
}
}
else
Clear();
}
//从操作数栈中取出两个操作数
bool Calculator::Get2Operands(double & left,double & right)
{
if(s.IsEmpty()) //栈空
{
cerr<<"Missing Right Operand!"<<endl;
return false;
}
s.Pop(right);
if(s.IsEmpty())
{
cerr<<"Missing Left Operand!"<<endl;
return false;
}
s.Pop(left);
return true;
}
//将操作数的值value进操作栈
void Calculator::AddOperand(double value)
{
s.Push(value);
}
int Calculator::isp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 1;
case '*':
case '/':
case '%':
return 5;
case '+':
case '-':
return 3;
case ')':
return 6;
}
return -1;
}
int Calculator::icp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 6;
case '*':
case '/':
case '%':
return 4;
case '+':
case '-':
return 2;
case ')':
return 1;
}
return -1;
}
#include "LinkedStack.h"
#include <cmath>
class Calculator
{
public:
Calculator()
{
t.MakeEmpty();
t.Push('#'); //栈底放一个'#'
}
void Run(); //执行表达式计算
void Clear(); //清栈
private:
void AddOperand(double value); //操作数进栈
bool Get2Operands(double & left,double & right); //从栈中退出两个操作数
void DoOperator(char op); //形成运算指令,进行计算
int isp(char ch); //判断操作符的栈内优先数
int icp(char ch); //判断操作符的栈外优先数
LinkedStack<double> s; //栈对象定义,用于后缀表达式的计算过程,存储操作数
4000
LinkedStack<char> t; //栈对象定义,用于中缀表达式转后续表达式的过程,存储操作符
};
//读字符串并求一个后缀表达式的值,以字符'#'结束
void Calculator::Run()
{
char ch,ch1,op;
double newoperand;
cin>>ch;
while(1)
{
if(isdigit(ch)) //是操作数
{
//cout<<ch;
cin.putback(ch); //将字符放回输入流
cin>>newoperand; //重新读取操作数
AddOperand(newoperand); //将操作数放入栈中
cin>>ch; //读取下一扫描项
}
else
{
t.GetTop(ch1); //取栈顶操作符ch1
if (isp(ch1)<icp(ch)) //新输入操作符优先级高
{
t.Push(ch); //进栈
cin>>ch; //读取下一扫描项
}
else if (isp(ch1)>icp(ch)) //新输入操作符优先级低
{
t.Pop(op); //退栈
switch(op)
{
case '+':
case '-':
case '*':
case '/':
DoOperator(op); //是操作符,执行计算
break;
}
}
else //输入操作符优先级等于栈顶优先级
{
if(ch == '#')
break;
t.Pop(op);
if(op == '(')
cin>>ch;
}
}
}
assert(!s.IsEmpty());
double temp;
s.Pop(temp);
cout<<"The result is:"<<temp<<endl;
}
//清栈
void Calculator::Clear()
{
s.MakeEmpty();
}
//取两个操作数,根据操作符op形成运算指令并计算
void Calculator::DoOperator(char op)
{
double left,right;
bool result;
result = Get2Operands(left,right);
if(result == true)
{
switch(op)
{
case '+':
s.Push(left+right);
break;
case '-':
s.Push(left-right);
break;
case '*':
s.Push(left*right);
break;
case '/':
if(right == 0.0)
{
cerr<<"Divided by 0!"<<endl;
Clear();
exit(0);
}
else
s.Push(left/right);
break;
}
}
else
Clear();
}
//从操作数栈中取出两个操作数
bool Calculator::Get2Operands(double & left,double & right)
{
if(s.IsEmpty()) //栈空
{
cerr<<"Missing Right Operand!"<<endl;
return false;
}
s.Pop(right);
if(s.IsEmpty())
{
cerr<<"Missing Left Operand!"<<endl;
return false;
}
s.Pop(left);
return true;
}
//将操作数的值value进操作栈
void Calculator::AddOperand(double value)
{
s.Push(value);
}
int Calculator::isp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 1;
case '*':
case '/':
case '%':
return 5;
case '+':
case '-':
return 3;
case ')':
return 6;
}
return -1;
}
int Calculator::icp(char ch)
{
switch (ch)
{
case '#':
return 0;
case '(':
return 6;
case '*':
case '/':
case '%':
return 4;
case '+':
case '-':
return 2;
case ')':
return 1;
}
return -1;
}
相关文章推荐
- 计算一个字符串表示的四则运算表达式
- 计算出用字符串表示的数学表达式的值
- 中序表达式的表示法与计算方法
- 自己写的程序expr,以计算从命令行输入的逆波尔表达式的值,其中每个运算符或操作数用一个单独的参数表示
- javascript:逆波兰式表示法计算表达式结果
- 给定一个表示分数加减表达式的字符串,需要以字符串格式返回计算结果。结果表达式也是分数式
- 计算出用字符串表示的数学表达式的值
- 了解中序表达式的表示法与计算方法 (转)
- javascript:逆波兰式表示法计算表达式结果
- 计算一个数的二进制表示中1的个数
- 四则表达式计算模板第二版
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 栈-----括号匹配+表达式计算
- 输入一个int型数据,计算出该int型数据在内存中存储时1的个数以及相应二进制表示
- 字符串四则运算表达式的计算(华为机试)
- 表达式计算类 (C#)
- leetcode_461. Hamming Distance 计算汉明距离,按位异或运算,计算整数的二进制表示中1的个数 java
- 注意Java正则表达式的数量表示符
- HDU 2424-Gary's Calculator(表达式计算+大数)
- C语言练习 表达式的递归计算