求助!!输入中缀表达式计算结果

降龙 2011-05-22 09:00:45
对C++不是很熟悉,现在出于需要要用C++写一个计算器,求助啊!!
现在知道如何将控制台输入的中缀变成后缀,知道如何计算从控制台输入的后缀表达式,但是不知道如何将变换后的后缀表达式传递给计算函数,现有的代码如下:

变量声明:
stack<double> num; //存放操作数
stack<char> s; //存放表达式转换过程中的变量

中缀转后缀:

// 定义在堆栈外面时运算符的优先级
int isp(char c) {
if (c == '+' || c =='-')
return 3;
else if (c == '*' || c == '/')
return 5;
else if (c == '(')
return 1;
else if (c == ')')
return 7;
else
return 0;
}

// 定义在堆栈外面时运算符的优先级
int osp(char c) {
if (c == '+' || c =='-')
return 2;
else if (c == '*' || c == '/')
return 4;
else if (c == '(')
return 7;
else if (c == ')')
return 1;
else
return 0;
}
//中缀表达式转后缀表达式
void InfixToPostfix()
{
char ch, y;
s.push('#');
while (cin>>ch,ch != '#') {
if (isdigit(ch) || isalpha(ch))
cout<<ch; //扫描到操作数直接输出
else if (ch == ')') //扫描到右括号时的处理
for (y = s.top(), s.pop(); y != '('; y = s.top(), s.pop())
cout<<ch;
else { //扫描到其它操作符时的处理
for (y = s.top(), s.pop(); osp(ch) < isp(y); y = s.top(), s.pop()) //弹出栈顶操作符
cout<<ch; //刚弹出的栈顶操作符的优先级高时输出
s.push(y); //当刚弹出的栈顶操作符的优先级低时,将其重新压回栈中
s.push(ch); //然后扫描到的操作符进栈
}
}
//输出栈中剩余操作符
while (!s.empty()){
y = s.top();
s.pop();
if (y != '#')
cout<<y;
}
}

计算后缀表达式:

//出错后清空
void Clear()
{
while(num.empty())
num.pop();
}
void PushOperand(double op)
{
num.push(op);
}

//获取操作数
bool GetOperands(double &op1, double &op2)
{
if (num.empty()){
cerr<<"Missing operand!"<<endl;
return false;
}
op1 = num.top();
num.pop();
if (num.empty()){
cerr<<"Missing operand!"<<endl;
return false;
}
op2 = num.top();
num.pop();
return true;
}

//处理操作符
void DoOperator(char oper)
{
bool result;
double oper1,oper2;
result = GetOperands(oper1,oper2); //从栈中弹出2个操作数
if (result)
switch(oper) //根据操作符做相应的运算,先出栈的操作数oper1
{ //放在操作符的右边,后出栈的oper2放在左边
case '+': num.push(oper2+oper1); break;
case '-': num.push(oper2-oper1); break;
case '*': num.push(oper2*oper1); break;
case '/':
if (fabs(oper1)<1e-6) { //如果分母为0,则做出错处理
cerr<<"Divide by 0!"<<endl;
Clear();
}
else
num.push(oper2/oper1); break;
case '^': num.push(pow(oper2,oper1)); break;
}
else Clear();
}

//计算表达式
void Run()
{
char c;
double newop;
while (cin>>c,c!='#') { //从输入流试读入一个字符,遇结束符结束
switch(c) { //读入的字符做如下处理
case '+':
case '-':
case '*':
case '/':
case '^': DoOperator(c); break; //是操作符则进行相应的计算
default: cin.putback(c); //如不是操作符,则将试读入的字符放回输入流
cin>>newop; //读入一个操作数
PushOperand(newop); break; //操作数进栈
}
}
}
...全文
375 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
selooloo 2011-05-22
  • 打赏
  • 举报
回复
帮LZ简单改了下,不过貌似原程序还有些问题

#include <iostream>
#include <vector>
#include <stack>
#include <sstream>
#include <cmath>

using namespace std;

stack<double> num; //存放操作数
stack<char> s; //存放表达式转换过程中的变量
string expr;
int isp(char c) {
if (c == '+' || c =='-')
return 3;
else if (c == '*' || c == '/')
return 5;
else if (c == '(')
return 1;
else if (c == ')')
return 7;
else
return 0;
}

// 定义在堆栈外面时运算符的优先级
int osp(char c) {
if (c == '+' || c =='-')
return 2;
else if (c == '*' || c == '/')
return 4;
else if (c == '(')
return 7;
else if (c == ')')
return 1;
else
return 0;
}
//中缀表达式转后缀表达式
void InfixToPostfix()
{
char ch, y;
s.push('#');
while (cin>>ch,ch != '#') {
if (isdigit(ch) || isalpha(ch))
{
//cout<<ch; //扫描到操作数直接输出
expr.push_back(ch);
expr.push_back(' ');
}
else if (ch == ')') //扫描到右括号时的处理
for (y = s.top(), s.pop(); y != '('; y = s.top(), s.pop())
{
cout<<ch; //扫描到操作数直接输出
}
else { //扫描到其它操作符时的处理
for (y = s.top(), s.pop(); osp(ch) < isp(y); y = s.top(), s.pop()) //弹出栈顶操作符
{
cout<<ch; //扫描到操作数直接输出
} //刚弹出的栈顶操作符的优先级高时输出
s.push(y); //当刚弹出的栈顶操作符的优先级低时,将其重新压回栈中
s.push(ch); //然后扫描到的操作符进栈
}
}
//输出栈中剩余操作符
while (!s.empty()){
y = s.top();
s.pop();
if (y != '#')
{
//cout<<y;
expr.push_back(y);
expr.push_back(' ');
}
}
expr.push_back('#');
}

void Clear()
{
while(num.empty())
num.pop();
}
void PushOperand(double op)
{
num.push(op);
}

//获取操作数
bool GetOperands(double &op1, double &op2)
{
if (num.empty()){
cerr<<"Missing operand!"<<endl;
return false;
}
op1 = num.top();
num.pop();
if (num.empty()){
cerr<<"Missing operand!"<<endl;
return false;
}
op2 = num.top();
num.pop();
return true;
}

//处理操作符
void DoOperator(char oper)
{
bool result;
double oper1,oper2;
result = GetOperands(oper1,oper2); //从栈中弹出2个操作数
if (result)
switch(oper) //根据操作符做相应的运算,先出栈的操作数oper1
{ //放在操作符的右边,后出栈的oper2放在左边
case '+': num.push(oper2+oper1); break;
case '-': num.push(oper2-oper1); break;
case '*': num.push(oper2*oper1); break;
case '/':
if (fabs(oper1)<1e-6) { //如果分母为0,则做出错处理
cerr<<"Divide by 0!"<<endl;
Clear();
}
else
num.push(oper2/oper1); break;
case '^': num.push(pow(oper2,oper1)); break;
}
else Clear();
}

//计算表达式
void Run()
{
char c;
double newop;
stringstream ss(expr);
while (ss>>c,c!='#') { //从输入流试读入一个字符,遇结束符结束
switch(c) { //读入的字符做如下处理
case '+':
case '-':
case '*':
case '/':
case '^': DoOperator(c); break; //是操作符则进行相应的计算
default: ss.putback(c); //如不是操作符,则将试读入的字符放回输入流
ss>>newop; //读入一个操作数
PushOperand(newop); break; //操作数进栈

}
}
}


int main(void)
{
InfixToPostfix();
Run();
cout<<num.top()<<endl;
system("pause");
return 0;
}

降龙 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 sryan 的回复:]

引用 10 楼 wuxianglong 的回复:
引用 8 楼 sryan 的回复:

引用 7 楼 wuxianglong 的回复:
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?

输入的存到string中,再分离到ve……
[/Quote]
嗯,谢谢啦。。。。
碎炎 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wuxianglong 的回复:]
引用 8 楼 sryan 的回复:

引用 7 楼 wuxianglong 的回复:
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?

输入的存到string中,再分离到vector<string>中,每个元素存一个数字或者一个……
[/Quote]
这个我自己写的。。。从头到尾扫字符串 数字push_back()操作符push_back()
应该还有更好的办法的 我这个是挺烦的

降龙 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sryan 的回复:]

引用 7 楼 wuxianglong 的回复:
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?

别称呼您不您的 听着别扭死了。。。
[/Quote]
呵呵,好的。。
降龙 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sryan 的回复:]

引用 7 楼 wuxianglong 的回复:
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?

输入的存到string中,再分离到vector<string>中,每个元素存一个数字或者一个操作符 然后按常规方法转换为后缀表达式
……
[/Quote]
C++字符串怎么分割啊?好像类库中没有这样的方法吧?
碎炎 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wuxianglong 的回复:]
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?
[/Quote]
别称呼您不您的 听着别扭死了。。。
碎炎 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wuxianglong 的回复:]
引用 6 楼 sryan 的回复:

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的

那您是如何将控制台输入的中缀表达式转化为后缀的啊?
[/Quote]
输入的存到string中,再分离到vector<string>中,每个元素存一个数字或者一个操作符 然后按常规方法转换为后缀表达式
降龙 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sryan 的回复:]

我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的
[/Quote]
那您是如何将控制台输入的中缀表达式转化为后缀的啊?
碎炎 2011-05-22
  • 打赏
  • 举报
回复
我以前做过 我好像是把每一个数字和操作符放到vector<string>里了 然后用atof转换为浮点计算的
yfk 2011-05-22
  • 打赏
  • 举报
回复
看下这个吧~
http://www.cnblogs.com/grandydong/archive/2007/03/02/661852.html
降龙 2011-05-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 selooloo 的回复:]

LZ代码更像C,后缀表达式以字符串保存,再写个以字符串为形参的接口函数不就行了吗,
[/Quote]
不好意思,我对C++不熟悉,这些基本上是从一本书上看到的,请问您说的具体怎么实现啊?谢谢啦!
yfk 2011-05-22
  • 打赏
  • 举报
回复
http://www.cnblogs.com/grandydong/archive/2007/03/02/661852.html
selooloo 2011-05-22
  • 打赏
  • 举报
回复
LZ代码更像C,后缀表达式以字符串保存,再写个以字符串为形参的接口函数不就行了吗,
ryfdizuo 2011-05-22
  • 打赏
  • 举报
回复

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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