高手帮帮忙~~~~一个有关计算器的小问题

lwc666 2009-04-22 11:35:12
[code=C/C++][/code#include<iostream>
using namespace std;
#define STACK_INIT_SIZE 100 // 定义栈的初始大小
#define STACKINCREMENT 10 //定义增量
typedef struct stackd // 定义double型结构体(栈)
{
double *base;
double *top;
int stacksize;
}SqStackd;
typedef struct stackchar //定义char类型的结构体(栈)
{
char *base;
char *top;
int stacksize;
}SqStackchar;
void InintStackd(SqStackd &s); //初始化数字栈函数
void InintStackchar(SqStackchar &s); //初始化符号栈函数
void Pushd(SqStackd &s,double e); //数字压栈函数
void Pushchar(SqStackchar &s,char e); //字符压栈函数
void Popd(SqStackd &s,double &e); //数字出栈函数
void Popchar(SqStackchar &s,char &e); //字符出栈函数
double GetTopd(SqStackd s); //数字得到栈顶元素函数
char GetTopchar(SqStackchar s); //字符的得到栈顶元素函数
void EvaluateExpression(SqStackd &OPND,SqStackchar &OPTR ); //计算器函数
double shuzhizhuanhuan(char * s); //将字符串型转换为double类型函数
char Precede(char d,char s); //判断符号优先级函数
double Operate(double a,char theata,double b); //运算函数
void main()
{
while(1)
{
SqStackchar OPTR; //定义字符型栈变量
SqStackd OPND; //定义数字型栈变量
InintStackd(OPND); //初始化数字栈
InintStackchar(OPTR); //初始化字符栈
EvaluateExpression(OPND,OPTR ); //计算
}
}
void InintStackd(SqStackd &s) //初始化数字栈函数
{
s.base=(double *)malloc(STACK_INIT_SIZE*sizeof(double)); //分配栈大小
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}
void InintStackchar(SqStackchar &s) //初始化符号栈函数
{
s.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char)); //分配栈大小
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}
void Pushd(SqStackd &s,double e) //数字压栈函数
{
if(s.top-s.base>=s.stacksize) //空间不够时重新分配空间
{
s.base=(double *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(double));
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
}
void Pushchar(SqStackchar &s,char e) //字符压栈函数
{
if(s.top-s.base>=s.stacksize) //空间不够时重新分配空间
{
s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char));
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
}
void Popd(SqStackd &s,double &e) //数字出栈函数
{
if(s.top==s.base)
cout<<"error"<<endl;
e=*(--s.top);
}
void Popchar(SqStackchar &s,char &e) //字符出栈函数
{
if(s.top==s.base)
cout<<"error"<<endl;
e=*(--s.top);
}
double GetTopd(SqStackd s) //数字得到栈顶元素函数
{
if(s.top==s.base)
return 0;
return *--s.top;
}
char GetTopchar(SqStackchar s) //字符的得到栈顶元素函数
{
if(s.top==s.base)
return 'F';
return *--s.top;
}
void EvaluateExpression(SqStackd &OPND,SqStackchar &OPTR ) //计算器函数
{



char *c=0;
c=new char[10];
char x,theta;
double flag;
double b,a;
Pushchar(OPTR,'#');
cout<<"请输入表达式 输入‘=’结束"<<endl;
cin>>c;
flag=shuzhizhuanhuan(c);
while((*c!='=')||(GetTopchar(OPTR)!='#'))
{
if(flag!=0)
{
Pushd(OPND,flag);
cin>>c;
flag=shuzhizhuanhuan(c);
}//if
else
{
switch(Precede(GetTopchar(OPTR),*c))
{
case'<' :
Pushchar(OPTR,*c);
cin>>c;
flag=shuzhizhuanhuan(c);
break;
case '=' :
Popchar(OPTR,x);
cin>>c;
flag=shuzhizhuanhuan(c);
break;
case '>' :
Popchar(OPTR,theta);
Popd(OPND,b);
Popd(OPND,a);
Pushd(OPND,Operate(a,theta,b));
break;
} //switch
} //else

} //while
cout<<"hello"<<endl;
cout<<GetTopd(OPND)<<endl;
} //EvaluateExpression
double shuzhizhuanhuan(char *s) //将字符串型转换为double类型函数
{
double i;
i=atof(s);
return i;
}
char Precede(char d,char s) //判断符号优先级函数
{
char t;
t=d;
if(((t=='+')||(t=='-'))&&((s=='+')||(s=='-')||(s==')')||(s=='=')))
return '>';
else if(((t=='+')||(t=='-'))&&((s=='*')||(s=='/')||(s=='(')))
return '<';
else if(((t=='*')||(t=='/'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='=')))
return '>';
else if(((t=='*')||(t=='/'))&&((s=='(')))
return '<';
else if(((t=='('))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')))
return '<';
else if(((t=='('))&&((s==')')))
return '=';
else if(((t==')'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='=')))
return '>';
else if(((t=='#'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s=='(')))
return '<';
else if((t=='#')&&(s=='='))
return '=';
else return 'F';
}
double Operate(double a,char theata,double b) //运算函数
{
switch(theata)
{
case '+' :
return (a+b);
break;
case '-' :
return (a-b);
break;
case '*' :
return (a*b);
break;
case '/' :
return (a/b);
break;
}//switch
}
这是一个计算器的程序,运行时输入的计算式必须是“2 + 3 * 4 =”之类的格式,也就是说每一个数字与符号之间都必须手动输入“ ”(空格),想请那位帮帮忙,让那个空格可以不用手动输入,也就是说实现“2+3*4=”这样的输入格式
...全文
196 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
lwc666 2009-04-26
  • 打赏
  • 举报
回复
呵呵,现在可以告诉你你的代码里的几个错误
1.无法计算负数的运算
2.c的输入应该用cin>> 至于为什么,我也不知道,但是用getchar()是有错的
3.压栈及出栈时char与double型混乱
不过也要谢谢你的提醒,让我知道可以用一个栈实现计算器,可以看看我新写的这个,有一部分就是用了你的思想
lwc666 2009-04-26
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;
#define STACK_INIT_SIZE 100 // 定义栈的初始大小
#define STACKINCREMENT 10 //定义增量
typedef struct stackd // 定义double型结构体(栈)
{
double *base;
double *top;
int stacksize;
}SqStackd;

void InintStackd(SqStackd &s); //初始化数字栈函数
void Pushd(SqStackd &s,double e); //数字压栈函数
void Popd(SqStackd &s,double &e); //数字出栈函数
double GetTopd(SqStackd s); //数字得到栈顶元素函数
void EvaluateExpression(SqStackd &OPND,SqStackd &OPTR ); //计算器函数
char Precede(double d,char s); //判断符号优先级函数
double Operate(double a,double theata,double b); //运算函数
void main()
{
while(1)
{
SqStackd OPND,OPTR; //定义数字型栈变量
InintStackd(OPND); //初始化数字栈
InintStackd(OPTR); //初始化字符栈
EvaluateExpression(OPND,OPTR ); //计算
}
}
void InintStackd(SqStackd &s) //初始化数字栈函数
{
s.base=(double *)malloc(STACK_INIT_SIZE*sizeof(double)); //分配栈大小
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}

void Pushd(SqStackd &s,double e) //数字压栈函数
{
if(s.top-s.base>=s.stacksize) //空间不够时重新分配空间
{
s.base=(double *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(double));
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
}

void Popd(SqStackd &s,double &e) //数字出栈函数
{
if(s.top==s.base)
cout<<"error"<<endl;
e=*(--s.top);
}

double GetTopd(SqStackd s) //数字得到栈顶元素函数
{
if(s.top==s.base)
return 0;
return *--s.top;
}
int StckLenth(SqStackd s) //计算栈中元素个数
{
int i=0;
double * t;
t=s.base;
while(t!=(s.top))
{
t++;
i++;
}
return i;
}
void EvaluateExpression(SqStackd &OPND,SqStackd &OPTR ) //计算器函数
{
char c;
char a[10];

double b,f,flag(0),x,theta;
Pushd(OPTR,'#');
cout<<"请输入表达式 输入‘#’结束"<<endl;
cin>>c;
while((c!='#')||(GetTopd(OPTR)!=35))
{
if((GetTopd(OPTR)==40&&c=='-')||((GetTopd(OPTR)==35)&&c=='-'&&StckLenth(OPND)==0))
flag=1;
else
flag=0;
if((c>='0'&&c<='9')||(c=='.')||flag==1)
{
int i(0);
while((c>='0'&&c<='9')||(c=='.')||flag==1)
{
a[i]=c;
i++;
cin>>c;
flag=0;
}

a[i]='\0';
double q=atof(a);
Pushd(OPND,q);
}//if
else
{
switch(Precede(GetTopd(OPTR),c))
{
case'<' :
Pushd(OPTR,(double)c);
cin>>c;
flag=0;
break;
case '=' :
Popd(OPTR,x);
cin>>c;
flag=0;
break;
case '>' :
Popd(OPTR,theta);
Popd(OPND,b);
Popd(OPND,f);
Pushd(OPND,Operate(f,theta,b));
break;
} //switch
} //else

} //while
cout<<"计算结果为: ";
cout<<GetTopd(OPND)<<endl;
} //EvaluateExpression
char Precede(double d,char s) //判断符号优先级函数
{
char t;
t= (char)d;
if(((t=='+')||(t=='-'))&&((s=='+')||(s=='-')||(s==')')||(s=='#')))
return '>';
else if(((t=='+')||(t=='-'))&&((s=='*')||(s=='/')||(s=='(')))
return '<';
else if(((t=='*')||(t=='/'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='#')))
return '>';
else if(((t=='*')||(t=='/'))&&((s=='(')))
return '<';
else if(((t=='('))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')))
return '<';
else if(((t=='('))&&((s==')')))
return '=';
else if(((t==')'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='#')))
return '>';
else if(((t=='#'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s=='(')))
return '<';
else if((t=='#')&&(s=='#'))
return '=';
else return 'F';
}
double Operate(double a,double theata,double b) //运算函数
{
char r;
r=(char)theata;
switch(r)
{
case '+' :
return (a+b);
break;
case '-' :
return (a-b);
break;
case '*' :
return (a*b);
break;
case '/' :
if(b!=0)
return (a/b);
else
{
cout<<"除数不能为零"<<endl;
exit(0);
}
break;
}//switch
}

这是一个新写的计算器,比原来的那个简单了好多,但功能没有变,谢谢大家的帮忙
ltc_mouse 2009-04-24
  • 打赏
  • 举报
回复
建议考虑下 cin.get(ch), cin.unget() 判断操作数和操作符, 而不是现在的直接读一个字符串~

用代码格式帮lz重发下,方便楼下同志调试,呵呵

#include <iostream>
using namespace std;
#define STACK_INIT_SIZE 100 // 定义栈的初始大小
#define STACKINCREMENT 10 //定义增量
typedef struct stackd // 定义double型结构体(栈)
{
double *base;
double *top;
int stacksize;
}SqStackd;
typedef struct stackchar //定义char类型的结构体(栈)
{
char *base;
char *top;
int stacksize;
}SqStackchar;
void InintStackd(SqStackd &s); //初始化数字栈函数
void InintStackchar(SqStackchar &s); //初始化符号栈函数
void Pushd(SqStackd &s,double e); //数字压栈函数
void Pushchar(SqStackchar &s,char e); //字符压栈函数
void Popd(SqStackd &s,double &e); //数字出栈函数
void Popchar(SqStackchar &s,char &e); //字符出栈函数
double GetTopd(SqStackd s); //数字得到栈顶元素函数
char GetTopchar(SqStackchar s); //字符的得到栈顶元素函数
void EvaluateExpression(SqStackd &OPND,SqStackchar &OPTR ); //计算器函数
double shuzhizhuanhuan(char * s); //将字符串型转换为double类型函数
char Precede(char d,char s); //判断符号优先级函数
double Operate(double a,char theata,double b); //运算函数

void main(void)
{
while(1)
{
SqStackchar OPTR; //定义字符型栈变量
SqStackd OPND; //定义数字型栈变量
InintStackd(OPND); //初始化数字栈
InintStackchar(OPTR); //初始化字符栈
EvaluateExpression(OPND,OPTR ); //计算
}
}

void InintStackd(SqStackd &s) //初始化数字栈函数
{
s.base=(double *)malloc(STACK_INIT_SIZE*sizeof(double)); //分配栈大小
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}
void InintStackchar(SqStackchar &s) //初始化符号栈函数
{
s.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char)); //分配栈大小
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
}
void Pushd(SqStackd &s,double e) //数字压栈函数
{
if(s.top-s.base>=s.stacksize) //空间不够时重新分配空间
{
s.base=(double *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(double));
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
}
void Pushchar(SqStackchar &s,char e) //字符压栈函数
{
if(s.top-s.base>=s.stacksize) //空间不够时重新分配空间
{
s.base=(char *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(char));
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
}
void Popd(SqStackd &s,double &e) //数字出栈函数
{
if(s.top==s.base)
cout <<"error" <<endl;
e=*(--s.top);
}
void Popchar(SqStackchar &s,char &e) //字符出栈函数
{
if(s.top==s.base)
cout <<"error" <<endl;
e=*(--s.top);
}
double GetTopd(SqStackd s) //数字得到栈顶元素函数
{
if(s.top==s.base)
return 0;
return *--s.top;
}
char GetTopchar(SqStackchar s) //字符的得到栈顶元素函数
{
if(s.top==s.base)
return 'F';
return *--s.top;
}
void EvaluateExpression(SqStackd &OPND,SqStackchar &OPTR ) //计算器函数
{
char *c=0;
c=new char[10];
char x,theta;
double flag;
double b,a;
Pushchar(OPTR,'#');
cout <<"请输入表达式 输入‘=’结束" <<endl;
cin>>c;
flag=shuzhizhuanhuan(c);
while((*c!='=')||(GetTopchar(OPTR)!='#'))
{
if(flag!=0)
{
Pushd(OPND,flag);
cin>>c;
flag=shuzhizhuanhuan(c);
}//if
else
{
switch(Precede(GetTopchar(OPTR),*c))
{
case '<' :
Pushchar(OPTR,*c);
cin>>c;
flag=shuzhizhuanhuan(c);
break;
case '=' :
Popchar(OPTR,x);
cin>>c;
flag=shuzhizhuanhuan(c);
break;
case '>' :
Popchar(OPTR,theta);
Popd(OPND,b);
Popd(OPND,a);
Pushd(OPND,Operate(a,theta,b));
break;
} //switch
} //else
} //while
delete []c;

cout <<"hello" <<endl;
cout <<GetTopd(OPND) <<endl;
} //EvaluateExpression

double shuzhizhuanhuan(char *s) //将字符串型转换为double类型函数
{
double i;
i=atof(s);
return i;
}
char Precede(char d,char s) //判断符号优先级函数
{
char t;
t=d;
if(((t=='+')||(t=='-'))&&((s=='+')||(s=='-')||(s==')')||(s=='=')))
return '>';
else if(((t=='+')||(t=='-'))&&((s=='*')||(s=='/')||(s=='(')))
return '<';
else if(((t=='*')||(t=='/'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='=')))
return '>';
else if(((t=='*')||(t=='/'))&&((s=='(')))
return '<';
else if(((t=='('))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')))
return '<';
else if(((t=='('))&&((s==')')))
return '=';
else if(((t==')'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s==')')||(s=='=')))
return '>';
else if(((t=='#'))&&((s=='+')||(s=='-')||(s=='*')||(s=='/')||(s=='(')))
return '<';
else if((t=='#')&&(s=='='))
return '=';
else
return 'F';
}
double Operate(double a,char theata,double b) //运算函数
{
double ret = 0.0;
switch(theata)
{
case '+' :
ret = (a+b);
break;
case '-' :
ret = (a-b);
break;
case '*' :
ret = (a*b);
break;
case '/' :
ret = (a/b);
break;
default:
break;
}//switch
return ret;
}
ujfj1986 2009-04-24
  • 打赏
  • 举报
回复
要不你就加一个char[],存储整个输入的字符串,再把每个字符进行操作。
Sou2012 2009-04-24
  • 打赏
  • 举报
回复
小心空格哦
lwc666 2009-04-24
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 mmoaay 的回复:]
引用 4 楼 HelloDan 的回复:
每当我看到这么乱的代码我都心发凉

我的心也发凉
[/Quote]
嗯~~不帮忙就算了嘛,为什么总是打击人家积极性(⊙o⊙)?或者教教我怎么贴代码也行嘛,只知道在一边看笑话~~
ltc_mouse 2009-04-24
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 lwc666 的回复:]
引用 15 楼 ltc_mouse 的回复:
建议考虑下 cin.get(ch), cin.unget() 判断操作数和操作符, 而不是现在的直接读一个字符串~

首先谢谢你了~~能具体讲讲这两个函数的用法吗~~?
[/Quote]
unget回退上一次操作,即取消输入.利用它,可以输入字符,判断是操作符还是操作数,如果为操作数,就回退那个数字,按double类型读入操作数.写了一小段代码,你参考下~ 刚也粗略看了下16楼的代码,基本结构似乎跟lz的代码差不多(输入部分差别比较大);至于不能运行,会不会是'<'问题(注意没有,这个字符被莫名其妙的加了个空格,这是建议用代码块发代码的一个最重要原因了...)

int main()
{
char ch, op='#';
double val=0.0;
int done = 0;
while(!done && cin>>ch)
{
switch(ch)
{
case '+': case '-': case '*': case '/':
op = ch;
break; //运算符
case '(': case ')':
break; //括号
case '=':
done = 1;
break; //等号
case ' ': case '\t': case '\r':
break; //空白字符
default:
if( ('0'<= ch && ch <= '9') || '.' == ch )
{
cin.unget(); //操作数,所以回退刚读入的字符
cin>>val; //读入操作数
}
else
{
cerr<<"Unknown char found!"<<endl;
done = 1;
}
break;
}
}
cout<<"op = "<< op <<endl;
cout<<"val = "<< val<<endl;
return 0;
}
T技术沙龙 2009-04-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 HelloDan 的回复:]
每当我看到这么乱的代码我都心发凉
[/Quote]
我的心也发凉
  • 打赏
  • 举报
回复
[Quote=引用楼主 lwc666 的帖子:]
[code=C/C++][/code#include <iostream> 

[/Quote]真乱啊~~看出楼主是想贴代码的,但貌似不知道如何贴是吧~~
先mark,慢慢看
lwc666 2009-04-24
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 ltc_mouse 的回复:]
建议考虑下 cin.get(ch), cin.unget() 判断操作数和操作符, 而不是现在的直接读一个字符串~
[/Quote]
首先谢谢你了~~能具体讲讲这两个函数的用法吗~~?
lwc666 2009-04-24
  • 打赏
  • 举报
回复
嘿嘿,运行过了,没有运行我也不敢胡说嘛~~
不知道你看我的代码没有,我的是以字符串读入的,所以不能用getchar()~~~~~
mary0208 2009-04-24
  • 打赏
  • 举报
回复
不能输入字符串读入字符串再分析吗?这样就没有空格了
qqweinizhizhuo 2009-04-24
  • 打赏
  • 举报
回复
楼上的,你可以运行一下再说嘛,你说比较算符优先级的时候没有转换成char型的,那char n=char(theta)算不算转换呢?另外,要是一个计算器不能计算实型的数,拿这个计算器就不能称做一个完整的计算器。还有,就是你的问题,cin是带有缓冲的,所以推荐你用getchar()函数。它是一个字符一个字符读入的,这样你就可以实现你所希望的要求了
lwc666 2009-04-24
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 qqweinizhizhuo 的回复:]
同学,你写的太乱了,逻辑性不强!我给你一给你一个参考一下!
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef double SElemType;
/////////////////////////////////////////////////////////////////////////////////
/*以下为栈的操作*/

typedef struct SqStack //栈的顺序存储结构
{
S…
[/Quote]
首先谢谢你的回复,不过,不知道阁下是在哪里找的这段代码,还是自己写的,根本就算不出答案,而且你的代码里逻辑相当混乱,首先,你的栈是double型的,所以压入栈里的都是以double型存储的,所以在出栈后还是double型的,应该转换为字符型再经行符号优先级以及数字和字符的判断以确定得到的栈顶压入哪一个栈,,但是在这段代码里,char与double混用,根本不可能算出答案,建议你用两个栈一个double一个char
再次说一下我的问题:
这是一个计算器的程序,运行时输入的计算式必须是“2 + 3 * 4 =”之类的格式,也就是说每一个数字与符号之间都必须手动输入“ ”(空格)才能算出答案,想请那位帮帮忙,让那个空格可以不用手动输入,也就是说实现“2+3*4=”这样的输入格式 (这段代码是可以运行的,并且输入后可以真确计算出结果,现在的问题就是输入表达式的格式问题)

o0MyBelieve0o 2009-04-24
  • 打赏
  • 举报
回复
学习
ysysbaobei 2009-04-24
  • 打赏
  • 举报
回复
qqweinizhizhuo 2009-04-24
  • 打赏
  • 举报
回复
同学,你写的太乱了,逻辑性不强!我给你一给你一个参考一下!
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef double SElemType;
/////////////////////////////////////////////////////////////////////////////////
/*以下为栈的操作*/

typedef struct SqStack //栈的顺序存储结构
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
void InitStack (SqStack &S)//构造一个空栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));//分配储存空间
if(!S.base) exit (-1); //空间分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE; //空间初始分配
}//InitStack
bool GetTop (SqStack S,SElemType &e)
{ //若栈不空,则用e返回S的栈顶元素,并返回true;否则返回false
if(S.top==S.base)
return false;
e=*(S.top-1);
return true;
}//GetTop
bool Push(SqStack &S,SElemType e)
{ //插入元素为e的新的栈顶元素
if(S.top-S.base>=S.stacksize)
{ //栈满,追加存储空间
S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base)
exit(-1); //存储空间分配失败
S.top=S.base+S.stacksize;//此处内存有可能重新分配,S.base地址有可能会变,此句不能省
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;//top自增
return true;
}// Push
bool Pop(SqStack &S,SElemType &e)//若栈不空,则删除S的栈顶元素,用e返回其值
{
if(S.top==S.base)
return false;
e=*--S.top; //删除一个元素,top减一
return true ;
}// Pop
/////////////////////////////////////////////////////////////////////////////////////////////////
/*以下为判断符号优先级的函数*/

char Precede(char a1 ,char a2)//判定运算符的优先级。
{ //根据课本p53页的表3.1
char r;
switch(a2)
{
case'+': //此处由于加减几乎优先级一样,故放在一起
case'-':
if(a1=='('||a1=='#')
r='<';
else
r='>';
break;
case'*': //此处由于乘除优先级一样,故放在一起
case'/':
if(a1=='*'||a1=='/'||a1==')')
r='>';
else
r='<';
break;
case'(':
if(a1==')')
{
cout<<"括号匹配错误!"<<endl;
exit(-1);
}
else
r='<';
break;
case')':
if(a1=='(')
r='=';
else if(a1=='#')
{
cout<<"error!没有左括号"<<endl;
exit (-1);
}
else
r='>';
break;
case'#':
switch(a1)
{
case'#':
r='=';
break;
case'(':
cout<<"error!没有右括号"<<endl;
exit(-1);
default:
r='>';
}//switch
break;
}//switch
return r;
}//Precede

////////////////////////////////////////////////////////////////////////////////
/*判断是否为操作符的函数*/
bool In(char d)//判断c是否为七种运算符之一
{
switch(d)
{
case'+':
case'-':
case'*':
case'/':
case'(':
case')':
case'#':
return true;
default:
return false;
}//switch
}
///////////////////////////////////////////////////////////////////////////////
/*以下为 运算函数*/

SElemType Operate( SElemType a, SElemType theta, SElemType b )//Operate为进行二元运算的a theta b的函数
{
char n=char(theta);//此处把double型强制转换成int型,虽然会造成精度缺失,但本身theta是一个符号,也算是整型
switch(n) //转换后相当于和符号匹配ACSII码
{
case'+':
return a+b;
case'-':
return a-b;
case'*':
return a*b;
default:
if(b!=0)
return a/b;
else
{
cout<<"error!除数不能为零"<<endl;
exit(-1);
}
}//switch
}
/////////////////////////////////////////////////////////////////////
/*以下为运算表达式的函数*/
SElemType EvaluateExpression()
{ //算符表达式的优先算法。设OPTR和OPND分别为运算符栈和运算数栈
SqStack OPTR,OPND;
char c;
char Data[11];//定义此数组为了存放整数或小数
SElemType a,b,d,e;
InitStack(OPTR);//构造一个运算符栈
InitStack(OPND);//构造一个运算数栈
Push(OPTR,'#');//将#压入栈底
c=getchar();
GetTop(OPTR,e);
while(c!='#'||e!='#')//栈顶不是#号且输入不是#号
{
if(In(c))//是符号则进栈
{
switch(Precede(e,c))
{
case'<': //栈顶元素优先级低
Push(OPTR,c);
c=getchar();
break;
case'=': //脱括号并接受下一字符
Pop(OPTR,e);
c=getchar();
break;
case'>': //退栈并将运算结果入栈
Pop(OPTR,e);
Pop(OPND,b);
Pop(OPND,a);
Push(OPND,Operate(a,e,b));
break;
}//switch
}
else if(c>='0'&&c<='9'||c=='.')
{
int i=0;
while(c>='0'&&c<='9'||c=='.')
{
Data[i]=c;
i++;
c=getchar();
}
Data[i]='\0';//数字没有存满,输入字符串结束符
d=atof(Data);//此处是把数组里的数字,实际上是按字符串;转换为double类型,然后把浮点型数字入栈
Push(OPND,d);//atof函数的形参是指针类型,故用数组名
}
else
{
cout<<"error!输入错误!"<<endl;
exit(-1);
}
GetTop(OPTR,e);
}//while
GetTop(OPND,e);
return e;
}//EvaluateExpression
////////////////////////////////////////////////////////////////////////////
/*主函数main.cpp*/

int main()
{
SElemType result;
cout<<"请输入表达式,以#号结束"<<endl;
result=EvaluateExpression();
cout<<"结果为:"<<result<<endl;
return 0;
}
这样写更能体现C++的面向对象性和封装性
Cpp权哥 2009-04-23
  • 打赏
  • 举报
回复
你就反复进行“读数据读运算符”就是了,如果运算符是'='就应该完工了。
HelloDan 2009-04-23
  • 打赏
  • 举报
回复
每当我看到这么乱的代码我都心发凉
ujfj1986 2009-04-23
  • 打赏
  • 举报
回复
把cin>>a改成cin.get(a)就可以了。
加载更多回复(10)

65,210

社区成员

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

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