| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1180 人关注过本帖
标题:(求助)改写程序(算术表达式求值)
只看楼主 加入收藏
loveszc
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2006-9-12
收藏
 问题点数:0 回复次数:2 
(求助)改写程序(算术表达式求值)

希望大家帮忙把这个C++程序改成C程序.

//带括号的算术表达式求值 源程序清单
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#define ERROR -1
#define BLANK 0
#define DATA 1
#define KUOHAO1 5
#define KUOHAO2 2
#define ADD_OR_SUB 3
#define MUT_OR_DIV 4

const int size=500;

template <class Elem>class Stack;
template <class Elem>
class StackNode //堆栈的结点类
{
friend class Stack<Elem>;
Elem elem;
StackNode<Elem> *link;
StackNode (Elem e=0, StackNode<Elem> *l=NULL):elem(e),link(l)
{
//cout<<"elem is : "<<e<<endl;
}
};
template <class Elem>
class Stack
{
int number;
StackNode<Elem> *head;

public:
Stack():number(0),head(NULL){}
~Stack()
{
StackNode<Elem> *tmp=head;
while(head!=NULL)
{
head=head->link;
delete tmp;
tmp=head;
}
}

void Push(const Elem &e)
{
number++;
head=new StackNode<Elem>(e, head);
}
void MakeEmpty()
{
StackNode<Elem> *tmp=head;
while(head!=NULL)
{
head=head->link;
delete tmp;
tmp=head;
}
number=0;
}

void Pop()
{
assert(number!=0);
number--;
StackNode<Elem> *tmp=head;
head=head->link;
delete tmp;
}

Elem GetHead()
{
return head->elem;
}
int GetNumber() const { return number; }//返回堆栈中元素的数目
};

//计算类
class Caculator
{
private:
Stack<double> data;//数据栈
Stack<char> sign;//运算符栈
int flag; //标志位表示前一个输入的是数还是一个运算符
public:
Caculator()
{
flag=BLANK;
}
~Caculator(){}
int Prior(char ch) const// 返回运算符的优先级
{
switch(ch)
{
case ')': return 1;
case '+':
case '-': return 2;
case '*':
case '/': return 3;
case '(': return 5;
default: return -1;
}
}

void clearstream()// 清空输入流
{
char ch;
while(cin>>ch, ch!=';') ;
}
void done(char ch)//做一次二元运算
{
double a, b;
a=data.GetHead(); data.Pop();
b=data.GetHead(); data.Pop();
switch(ch)
{
case '+': b+=a;break;
case '-': b-=a;break;
case '*': b*=a;break;
case '/': b/=a;break;
default : break;
}
data.Push(b);
}

void Caculate()//计算主体
{
char ch;
double d;
while(cin>>ch, ch!=';')
{
if(ch>='0' && ch<='9' || ch=='.')//如果是一个0-9的数, 则输入一个实数
{
if(flag==DATA)
{
cout<<"Error input! 数字连写了"<<endl;
flag=ERROR;
clearstream();
return;
}

cin.putback(ch);
cin>>d;
data.Push(d);
flag=DATA;
}
else//如果输入的是字符, 则作出判断
{
int prio=Prior(ch);
char tempch, chprior;
switch( prio )
{
case -1: cout<<"Error input! 不允许的字符"<<endl;//非法字符
flag=ERROR;
clearstream();
return;

case 1: // 如果是一个后括号,
if(flag==ADD_OR_SUB || flag==MUT_OR_DIV)//如果运此括号前是一个运算符,则提示出错
{
flag=ERROR;
clearstream();
cout<<"Error input! 运算符后少了数据"<<endl;
return;
}
//如果它前面的是前括号,则表明括号中间没在数据,提示出错
if( flag==KUOHAO1 )
{
cout<<"ERROR! 括号中间没在数据"<<endl;
flag=ERROR;
clearstream();
return ;
}
tempch=sign.GetHead(); //是合法的运算, 取一个运算符
flag=KUOHAO2;

while(tempch!='(') //做完这一重括号内的所有运算
{ sign.Pop();
done(tempch);
if(sign.GetNumber()!=0)
{

tempch=sign.GetHead();

}
else //如果当前的后括号没有找到与其配对的前括号, 则提示出错
{
cout<<"Error input! 括号不配对"<<endl;
flag=ERROR;
clearstream();
return;
}

}
sign.Pop();
break;
case 2: //如果读入的是一个 + 或者 - 号,

//它前面的是一个 + 或者 - 号, 由提示出错
if(flag==ADD_OR_SUB || flag==MUT_OR_DIV )
{
cout<<"Error input! 运算符连用"<<endl;
flag=ERROR;
clearstream();
return;
}
//如果+前面没有数据,或者+是被写在括号里的,则向它的前面压入一个0到data
if( flag==BLANK || data.GetNumber() == 0 || flag == KUOHAO1 )
{
data.Push(0);//push 0 to stack
//sign.Push(ch);//push + / - to stack
}
//如果它前面是一个后括号,因后括号里的内容已经做过运算,故只当一个一般的来做
if( flag== KUOHAO2 || flag == DATA )
{
while( sign.GetNumber() && sign.GetHead()!='(' && Prior( sign.GetHead() ) >= Prior(ch) )
{
done( sign.GetHead() );
sign.Pop();
}
}
flag = ADD_OR_SUB;
sign.Push( ch );
break;

case 3: // 如果当前输入是一个 * 或者 / 号
//如果前一个输入是一个 * 或者 / 号
if(flag==MUT_OR_DIV || flag==ADD_OR_SUB )
{
cout<<"Error input! 运算符连用"<<endl;
flag=ERROR;
clearstream();
return;
}
//如果前面是一个前括号
if( flag==KUOHAO1 )
{
cout<<"ERROR! * / 不能直接接在( 后"<<endl;
flag=ERROR;
clearstream();
return ;
}
//如果它放在了表达式的开头
if(data.GetNumber()==0)
{
cout<<"Error input! * 或 / 不能放在表达式的开头"<<endl;
flag=ERROR;
clearstream();
return;
}
//如果它前面不只一个数字, 则做它前面的运算
if(data.GetNumber()!=1)
{
chprior=Prior(sign.GetHead());
if(chprior>=Prior(ch) && sign.GetHead()!='(')
{
chprior=sign.GetHead();
sign.Pop();
done(chprior);
}
}
sign.Push(ch);
flag=MUT_OR_DIV;
break;
case 5://如果当前的是一个前括号
// 如果它前面输入的是一个数据,则提示出错
if(flag==DATA)
{
cout<<"Error input! 数据后不能直接跟括号"<<endl;
flag=ERROR;
clearstream();
return;
}
sign.Push(ch);
flag=KUOHAO1;
break;
default :
cout<<"Error input! 非法字符: "<<ch<<endl;
flag=ERROR;
clearstream();
break;
}
}

}
if( sign.GetNumber() && sign.GetHead() == '(' )
{
cout<<"ERROR! 括号不配对!"<<endl;//前括号没有找到后括号
flag=ERROR;
return ;
}
if( flag==MUT_OR_DIV || flag == ADD_OR_SUB)
{
cout<<"ERROR!表达式没有写完"<< endl;
flag=ERROR;
return;
}
while(sign.GetNumber())
{
if( sign.GetHead() == '(' )
{
cout<<"ERROR! 括号不配对!"<< endl;
flag = ERROR;
return ;
}
done(sign.GetHead());
sign.Pop();
}
}

void OutPut()
{
if(flag==ERROR)
{
cout<<"输入错误<! NO ANSWER !>"<<endl;
}
else if(data.GetNumber()==0)
{
cout<<"空表达式:无结果!"<<endl;
}
else
{
cout<<" 答 案 = "<<data.GetHead()<<endl;
data.Pop();
}
}

void EnEmpty()
{
data.MakeEmpty();
sign.MakeEmpty();
flag=BLANK;
}
};

int main()
{
cout<<"____________欢迎使用_____________"<<endl<<endl;
cout<<"说明:"<<endl;
cout<<"1. 实数运算只支持 <+ - * />;"<<endl;
cout<<"2. 可以用();"<<endl;
cout<<"3. 表达式的末尾必以‘;‘结束."<<endl<<endl;
char ch;
Caculator cac;
for(; ;){
cout<<"使用CACULATOR < y | n > ";
cin>>ch;
if(ch=='y'|| ch=='Y')
{
cout<<"输入表达式: ";
cac.Caculate();
cac.OutPut();
cac.EnEmpty();
cout<<"************************************************"<<endl;
}
else if(ch=='n'|| ch=='N')
{
cout<<"__________________谢谢使用!___________________"<<endl;
cout<<endl;
break;
}
else
cout<<"请输入'y' 或'n'"<<endl;
}

return 0;
}

搜索更多相关主题的帖子: 算术 求值 表达 
2006-12-08 13:11
菜鸟上路
Rank: 4
等 级:贵宾
威 望:14
帖 子:1120
专家分:0
注 册:2006-3-21
收藏
得分:0 
为什么不自己改?

2006-12-08 17:19
loveszc
Rank: 1
等 级:新手上路
帖 子:31
专家分:0
注 册:2006-9-12
收藏
得分:0 
晕.我改得来还要你们帮忙啊.也不是说改不来.只是我们马上就要交了.没时间了啊.
2006-12-10 16:59
快速回复:(求助)改写程序(算术表达式求值)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030112 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved