判断运算符优先级的函数

花爺 2008-04-10 05:55:33
我想写一个表达式求值的程序,例如:2+4*3-(2+3)*5 -10/5
怎样判断两个运算符的优先级。
...全文
2447 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Cpp权哥 2008-04-10
  • 打赏
  • 举报
回复
这个程序还要用户在输入表达式之后再输入一次后缀表达式,而且只能进行10以内的数的运算。
楼主只需要知道如何判断运算符的优先级,这只需要一个函数就行,你可以自己再增加一些需要的运算符:

int priority(char op)
{
if(op=='+'||op=='-')//加减
return 1;
else if(op=='*'||op=='/'||op=='%')//乘除和求余
return 2;
else if(op=='^')//乘方
return 3;
else{//其它无效
cerr << "invalid operator " << op << "!" << endl;
return -1;
}
}

zgjxwl 2008-04-10
  • 打赏
  • 举报
回复 1
直接贴个程序上去楼主自己看看把
//main.cpp
#include <iostream>
#include <ctype.h>
#include <math.h>
using namespace std;
#include "Calculator.h"
int main()
{
Calculator dstk(20); //声明一个对象,此时进行初始化.构造了容量为20的栈s
dstk.Push('#'); //初始时将'#'压入栈中
dstk.InfixToPostfix(dstk); //将中缀表达式转换为后缀表达式
dstk.Pop(); //删除遗留在栈s中的#号,使栈s用于计算后缀表达式用
dstk.Eval(dstk); //计算(后缀)达式的值
dstk.OutPut(dstk); //输出表达式结果
return 0;
}
//Calculator.h
enum ResultCode{Underflow,Overflow,MissingOperand,DivideByZero};
//计算器类
class Calculator
{
public:
Calculator(int mSize); //构造函数
bool IsEmpty(){return (top==-1);}
bool IsFull(){return (top==maxSize);}
int isp(char c); //栈内优先级函数
int icp(char c); //栈外优先级函数
void Push(const char &x); //向栈中添加非数值(如运算符等)元素函数,中缀表达式转后缀时
void Pop(); //删除栈顶元素
int Top(); //返回栈顶元素
void InfixToPostfix(Calculator &dstk); //将中缀表达式转换为后缀表达式函数
void Eval(Calculator &dstk); //运行计算器函数
void Clear(Calculator &dstk); //清除计算器
void OutPut(Calculator &dstk); //输出计算结果
private:
int top,maxSize;
int *s; //栈S
void PushOperand(char x); //后缀表达式中,使操作数x进栈
void PushCalcuRes(int result); //使两个操作数的运算结果进栈
bool GetOperands(int &x,int &y,Calculator &dstk); //取出栈顶两个操作数x和y
void DoOperator(char op,Calculator &dstk); //取出栈顶两个操作数x和y,执行运算y<op>x
};

Calculator::Calculator(int mSize)
{ //构造函数的实现
maxSize=mSize;
s=new int[maxSize];
top=-1;
}

int Calculator::isp(char c)
{
//计算运算符c的栈内优先级
int priority;
switch(c)
{
case '(':priority=0;break;
case '+':
case '-':priority=5;break;
case '*':
case '/':priority=6;break;
case '#':priority=0;break;
}
return priority;
}

int Calculator::icp(char c)
{
//计算运算符c的栈内优先级
int priority;
switch(c)
{
case '(':priority=8;break;
case '+':
case '-':priority=5;break;
case '*':
case '/':priority=6;break;
case '#':priority=0;break;
}
return priority;
}

void Calculator::Push(const char &x)
{ //使运算符进栈
if(IsFull())
throw Overflow;
s[++top]=x; //新元素进栈,一定要注意前缀加与后缀加的区别
}

void Calculator::Pop()
{
//删除栈顶元素
if(IsEmpty())
throw Underflow;
top--;
}

int Calculator::Top()
{
//返回栈顶元素
if(IsEmpty())
throw Underflow;
return s[top];
}
void Calculator::InfixToPostfix(Calculator &dstk)
{
//将中缀表达式转换为后缀表达式
char ch,y;
cout<<"请输入你要计算的表达式,以#号结束:";
while(cin>>ch,ch!='#')
{
if(isdigit(ch)||isalpha(ch))
cout<<ch;
else if(ch==')')
for(y=dstk.Top(),dstk.Pop();y!='(';y=dstk.Top(),dstk.Pop())
cout<<y;
else
{
for(y=dstk.Top();icp(ch)<=isp(dstk.Top());dstk.Pop())
cout<<y;
dstk.Push(ch); //当前运算符进栈
}
}
while ((dstk.IsEmpty()==false)&&(dstk.Top()!='#'))
{
y=dstk.Top();
dstk.Pop();
cout<<y;
}
cout<<endl;
}

void Calculator::Eval(Calculator &dstk)
{
//运行计算器函数
char m; //注意,这里是字符类型的,同样可以运算,只是是转换为对应的ASCII参与运算的(我在这里犯了错误)
cout<<"请输入上面计算下来的后缀表达式:"<<endl;
while (cin>>m,m!='#')
{
switch(m)
{
case '+':
case '-':
case '*':
case '/':
case '^':
DoOperator(m,dstk);
break;
default:
//cout<<"需要进栈的元素为:"<<m<<endl; //为了测试需要进栈的元素而加。纯属调试之用
dstk.PushOperand(m); //使操作数m进栈
//cout<<"而实际进栈的元素为:"<<s[top]<<endl; //为了测试实际进栈的元素而加。纯属调试之用
}
}
}

void Calculator::Clear(Calculator &dstk)
{
//清除计算器
dstk.Clear(dstk);
}

void Calculator::OutPut(Calculator &dstk)
{
int result;
result=dstk.Top();
cout<<"所计算的表达式的值为:"<<result<<endl;
}

void Calculator::PushOperand(char m)
{
//操作数m进栈,注意,此时m是个字符,m的值是它对应的ASCII码的值(在机器内的16进制表示)
int t=m;//此时计算时用的是m的ASCII码的值,不过在机器内是用16进制表示的,这里是将其转换为10进制表示,并赋给t
if(IsFull())
throw Overflow;
t=m-48; //将其转换为对应的整型数(描述可能有点不妥),然后进栈
s[++top]=t;
}

void Calculator::PushCalcuRes(int result)
{
if(IsFull())
throw Overflow;
s[++top]=result;
}
bool Calculator::GetOperands(int & x,int &y,Calculator &dstk)
{
//取出栈顶两个操作数x和y,执行运算y<op>x
if(dstk.IsEmpty())
throw MissingOperand; //抛出下溢异常
else
{
x=dstk.Top(); //返回栈顶元素并将其转换为其对应的ASCII码值的16进制表示,类型的强制转换
dstk.Pop();
}
if(dstk.IsEmpty())
throw MissingOperand;
else
{
y=dstk.Top(); //返回栈顶元素并将其转换为其对应的ASCII码值的16进制表示,将栈内的整型数进行
dstk.Pop();
}
return true;
}

void Calculator::DoOperator(char op,Calculator &dstk)
{
//计算(后缀)表达式的值
bool result;
int x,y;
result=GetOperands(x,y,dstk); //获取两个操作数
if(result) //判断是否获取成功
switch(op)
{
case '+':dstk.PushCalcuRes(y+x);break;
case '-':dstk.PushCalcuRes(y-x);break;
case '*':dstk.PushCalcuRes(y*x);break;
case '/':
if(x==0)
throw DivideByZero;
else
dstk.PushCalcuRes(y/x);
break;
case '^':dstk.PushCalcuRes(pow(y,x));break;
}
else
Clear(dstk);

}
kakaying 2008-04-10
  • 打赏
  • 举报
回复
一般的数据结构教材里应该都有介绍吧,建议查阅一下相关资料
kakaying 2008-04-10
  • 打赏
  • 举报
回复 1
可以自己设计优先级矩阵判断
比如下面的矩阵数据:
取矩阵[y][x]的值是否为1判断优先
+ - * /
+ 1 1 0 0
- 1 1 0 0
* 1 1 1 1
/ 1 1 1 1
第1章 PHP 5基础 1.1 简介 1.1.1 PHP是什么 1.1.2 初步认识PHP代码 1.2 PHP的安装 1.2.1 Linux下安装.Apache和PHP 1.2.2 Windows下安装Apache和PHP 1.3 PHP配置 1.3.1 PHP配置文件 1.3.2 PHP常用配置选项 1.3.3 加载扩展库 1.4 本章小结 第2章 网站开发语法基础 2.1 基本语法 2.2 数据类型 2.2.1 布尔型 2.2.2 整型 2.2.3 浮点型 2.2.4 字符串 2.2.5 数组 2.2.6 对象 2.2.7 资源 2.2.8 NULL 2.2.9 类型转换 2.3 变量 2.3.1 变量的赋值 2.3.2 预定义变量 2.3.3 变量作用域 2.3.4 可变变量 2.4 常量 2.4.1 自定义常量 2.4.2 魔术常量 2.5 表达式 2.6 运算符 2.6.1 算术运算符 2.6.2 字符串运算符 2.6.3 比较运算符 2.6.4 逻辑运算符 2.6.5 位运算符 2.6.6 赋值运算符 2.6.7 数组运算符 2.6.8 类型运算符 2.6.9 错误控制运算符 2.6.10 执行运算符 2.6.11 运算符的优先级 2.7 流程控制 2.7.1 if结构 2.7.2 switch结构 2.7.3 while循环 2.7.4 for循环 2.7.5 foreach语句 2.7.6 declare语句 2.7.7 exit和retunl语句 2.8 包含代码 2.9 本章小结 第3章 函数 3.1 用户自定义函数 3.1.1 函数调用与函数定义 3.1.2 递归函数 3.2 函数的参数 3.2.1 按值传递参数 3.2.2 通过引用传递 3.2.3 默认参数值 3.2.4 可变长度参数列表 3.3 函数返回值 第4章 类与对象 第5章 字符串 第6章 数组 第7章 PHP高级应用技术 第8章 PHP模板 第9章 MySQL快速入门 第10章 MySQL数据库管理 第11章 MySQL5进阶 第12章 文章发布系统 第13章 电子商务系统

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧