利用栈来实现计算表达式的自动计算(二)
2009-11-15 16:14
281 查看
一、扫描一遍出结果的算法设置:
(1):设置两个栈,一个运算符栈,一个操作数栈。初始化后将"#"压入操作符栈中。
(2):顺序扫描,当输入为操作数时就将其压入操作数栈。
(3):当输入为运算符时,则比较输入运算符和运算符栈的栈顶运算符的优先级的大小。若输入运算符的优先级高于运算符栈栈顶运算符的优先级时,则将其输入到运算符栈;若运算符栈栈顶运算符的优先级高于输入运算符的优先级,则将栈中的运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;然后重新比较输入运算符和更新后的栈顶运算符的优先级的大小。
(4):当输入运算符为"("时,将"("直接入运算符栈。
(5):当输入运算符为")"时,将运算符栈栈顶运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;重复此操作直至运算符栈的栈顶元素为"(",并将"("弹出并抛弃。
(6):当扫描到"#"时,说明算术表达式已经扫描完毕,运算符栈依次出栈并从操作数栈中弹出两个操作数施以运算,将运算结果作为新的操作数输出到操作数栈,直至运算符栈栈顶为"#"时结束。
(7):最后操作数栈的栈顶元素即为运算结果,将其输出到屏幕。
对于优先级的比较,如果是同种运算符,那么在栈内的运算符的优先级就比在栈外的运算符的优先级大一;不同级的运算符它们的优先级大小按原来的大小排列
二、扫描一遍出结果的源代码:
#include <stdio.h>
#define StackSize 100
/*定义字符栈*/
typedef char ElemType;
typedef struct
{
ElemType data[StackSize];
int top;
}SqStack;
/*定义数值栈*/
typedef struct
{
double data[StackSize];
int top;
}dstack;
/*初始化数值栈*/
void DsInit(dstack *s)
{
s->top=-1;
}
/*压入数值栈*/
int Dpush(dstack *s,double e)
{
if(s->top<StackSize-1)
{
s->top=s->top+1;
s->data[s->top]=e;
return 1;
}
else
{
return 0;
}
}
/*出数值栈*/
double Dpop(dstack *s)
{
double e;
if(-1==s->top)
{
return 1;
}
else
{
e=s->data[s->top];/*出栈*/
(s->top)--;
return e;
}
}
/*初始化字符栈操作*/
void InitStack(SqStack *s)
{
s->top=-1;
}
/*压入字符栈操作*/
int push(SqStack *s,ElemType e)
{
if(s->top<StackSize-1)
{
s->top=s->top+1;
s->data[s->top]=e;
return 1;
}
else
{
return 0;
}
}
/*出字符栈操作*/
ElemType pop(SqStack *s)
{
ElemType e;
if(-1==s->top)
{
return 1;
}
else
{
e=s->data[s->top];
(s->top)--;
return e;
}
}
/*取栈顶操作*/
int GetTop(SqStack s,ElemType *e)
{
if (0==s.top)
{
*e=s.data[s.top];
return 0;
}
else
{
*e=s.data[s.top];
return 1;
}
}
/* 比较优先级 */
int Get_Pri(int mode,char oper)
{/* 返回运算符oper代表优先级得整数值,mode为1,表示oper是栈顶运算符,否则是当前运算符 */
int tmp;
switch(oper)
{
case '#': tmp=0;break;
case '(': tmp=(mode? 1:6);break;
case '+':
case '-': tmp=(mode? 3:2);break;
case '*':
case '%':
case '/': tmp=(mode? 5:4);break;
case ')': tmp=(mode? 7:1);break;
}
return tmp;
}
char precede(char w,char ch)
{/* 判定运算符栈的栈顶运算符w,与当前运算符ch之间的优先关系 */
/* 取得栈顶运算符与当前运算符得优先级 */
int grade;
grade=Get_Pri(1,w)-Get_Pri(0,ch);
if(grade>0)
return '>';
else
{
if(grade==0)
return '=';
else
return '<';
}
}
/*用于计算的函数*/
void jisuan(char s,dstack *ds)
{
double ch;
switch(s)
{
case '+':
ch=Dpop(ds);ch+=Dpop(ds);Dpush(ds,ch);
break;
case '-':
ch=Dpop(ds);ch=Dpop(ds)-ch;Dpush(ds,ch);
break;
case '*':
ch = Dpop(ds);ch *= Dpop(ds);Dpush(ds,ch);
break;
case '/':
ch = Dpop(ds);ch = Dpop(ds) / ch;Dpush(ds,ch);
break;
case '%':
ch = Dpop(ds);ch = (double)((int)Dpop(ds)%(int)ch);
Dpush(ds,ch);
break;
}
}
/*扫描算术表达式的函数*/
double comp(char arr[])
{
SqStack s1;
dstack s2;
char ch,w='/0';
int i=0;
double x=0,d=1;
InitStack(&s1);
DsInit(&s2);
push(&s1,'#');
ch=arr[i];
while(ch!='#')
{
if('0'<=ch && ch<='9')
{
if('0'<=ch && ch<='9')
{
while('0'<=ch && ch<='9')
{
x=x*10+(ch-'0');
i=i+1;
ch=arr[i];
}
if(ch=='.')
{
ch=arr[++i];
while('0'<=ch && ch<='9')
{
d=d*10;
x=x+(ch-'0')/d;
ch=arr[++i];
}
}
}
Dpush(&s2,x);
x=0;
d=1;
}
/*扫描到运算运算符的处理程序*/
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%'||ch=='('||ch==')'||ch=='#')
{ GetTop(s1,&w);
while(precede(w,ch)=='>')
{
jisuan(pop(&s1),&s2);
GetTop(s1,&w);
}
if (precede(w,ch)=='<')
push(&s1,ch);
else
{
if (precede(w,ch)=='='&& ch!='#')
pop(&s1);
}
ch=(ch!='#') ? arr[++i] : ch;
}
}
GetTop(s1,&w);
while(w!='#')
{
jisuan(pop(&s1),&s2);
GetTop(s1,&w);
}
return Dpop(&s2);
}
/*主函数*/
void main()
{
char str[100];
char *yzh;
printf("Please input the infix express with a '#' in the end :");/*输入表达式并以#号结束*/
gets(str);
yzh=str;
printf("The infix express is:%s/n",yzh);
printf("/nThe result is:%f/n/n",comp(str));
}
(1):设置两个栈,一个运算符栈,一个操作数栈。初始化后将"#"压入操作符栈中。
(2):顺序扫描,当输入为操作数时就将其压入操作数栈。
(3):当输入为运算符时,则比较输入运算符和运算符栈的栈顶运算符的优先级的大小。若输入运算符的优先级高于运算符栈栈顶运算符的优先级时,则将其输入到运算符栈;若运算符栈栈顶运算符的优先级高于输入运算符的优先级,则将栈中的运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;然后重新比较输入运算符和更新后的栈顶运算符的优先级的大小。
(4):当输入运算符为"("时,将"("直接入运算符栈。
(5):当输入运算符为")"时,将运算符栈栈顶运算符弹出并从操作数栈中弹出两个操作数施以运算,将运算结果作为操作数输出到操作数栈;重复此操作直至运算符栈的栈顶元素为"(",并将"("弹出并抛弃。
(6):当扫描到"#"时,说明算术表达式已经扫描完毕,运算符栈依次出栈并从操作数栈中弹出两个操作数施以运算,将运算结果作为新的操作数输出到操作数栈,直至运算符栈栈顶为"#"时结束。
(7):最后操作数栈的栈顶元素即为运算结果,将其输出到屏幕。
对于优先级的比较,如果是同种运算符,那么在栈内的运算符的优先级就比在栈外的运算符的优先级大一;不同级的运算符它们的优先级大小按原来的大小排列
二、扫描一遍出结果的源代码:
#include <stdio.h>
#define StackSize 100
/*定义字符栈*/
typedef char ElemType;
typedef struct
{
ElemType data[StackSize];
int top;
}SqStack;
/*定义数值栈*/
typedef struct
{
double data[StackSize];
int top;
}dstack;
/*初始化数值栈*/
void DsInit(dstack *s)
{
s->top=-1;
}
/*压入数值栈*/
int Dpush(dstack *s,double e)
{
if(s->top<StackSize-1)
{
s->top=s->top+1;
s->data[s->top]=e;
return 1;
}
else
{
return 0;
}
}
/*出数值栈*/
double Dpop(dstack *s)
{
double e;
if(-1==s->top)
{
return 1;
}
else
{
e=s->data[s->top];/*出栈*/
(s->top)--;
return e;
}
}
/*初始化字符栈操作*/
void InitStack(SqStack *s)
{
s->top=-1;
}
/*压入字符栈操作*/
int push(SqStack *s,ElemType e)
{
if(s->top<StackSize-1)
{
s->top=s->top+1;
s->data[s->top]=e;
return 1;
}
else
{
return 0;
}
}
/*出字符栈操作*/
ElemType pop(SqStack *s)
{
ElemType e;
if(-1==s->top)
{
return 1;
}
else
{
e=s->data[s->top];
(s->top)--;
return e;
}
}
/*取栈顶操作*/
int GetTop(SqStack s,ElemType *e)
{
if (0==s.top)
{
*e=s.data[s.top];
return 0;
}
else
{
*e=s.data[s.top];
return 1;
}
}
/* 比较优先级 */
int Get_Pri(int mode,char oper)
{/* 返回运算符oper代表优先级得整数值,mode为1,表示oper是栈顶运算符,否则是当前运算符 */
int tmp;
switch(oper)
{
case '#': tmp=0;break;
case '(': tmp=(mode? 1:6);break;
case '+':
case '-': tmp=(mode? 3:2);break;
case '*':
case '%':
case '/': tmp=(mode? 5:4);break;
case ')': tmp=(mode? 7:1);break;
}
return tmp;
}
char precede(char w,char ch)
{/* 判定运算符栈的栈顶运算符w,与当前运算符ch之间的优先关系 */
/* 取得栈顶运算符与当前运算符得优先级 */
int grade;
grade=Get_Pri(1,w)-Get_Pri(0,ch);
if(grade>0)
return '>';
else
{
if(grade==0)
return '=';
else
return '<';
}
}
/*用于计算的函数*/
void jisuan(char s,dstack *ds)
{
double ch;
switch(s)
{
case '+':
ch=Dpop(ds);ch+=Dpop(ds);Dpush(ds,ch);
break;
case '-':
ch=Dpop(ds);ch=Dpop(ds)-ch;Dpush(ds,ch);
break;
case '*':
ch = Dpop(ds);ch *= Dpop(ds);Dpush(ds,ch);
break;
case '/':
ch = Dpop(ds);ch = Dpop(ds) / ch;Dpush(ds,ch);
break;
case '%':
ch = Dpop(ds);ch = (double)((int)Dpop(ds)%(int)ch);
Dpush(ds,ch);
break;
}
}
/*扫描算术表达式的函数*/
double comp(char arr[])
{
SqStack s1;
dstack s2;
char ch,w='/0';
int i=0;
double x=0,d=1;
InitStack(&s1);
DsInit(&s2);
push(&s1,'#');
ch=arr[i];
while(ch!='#')
{
if('0'<=ch && ch<='9')
{
if('0'<=ch && ch<='9')
{
while('0'<=ch && ch<='9')
{
x=x*10+(ch-'0');
i=i+1;
ch=arr[i];
}
if(ch=='.')
{
ch=arr[++i];
while('0'<=ch && ch<='9')
{
d=d*10;
x=x+(ch-'0')/d;
ch=arr[++i];
}
}
}
Dpush(&s2,x);
x=0;
d=1;
}
/*扫描到运算运算符的处理程序*/
if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='%'||ch=='('||ch==')'||ch=='#')
{ GetTop(s1,&w);
while(precede(w,ch)=='>')
{
jisuan(pop(&s1),&s2);
GetTop(s1,&w);
}
if (precede(w,ch)=='<')
push(&s1,ch);
else
{
if (precede(w,ch)=='='&& ch!='#')
pop(&s1);
}
ch=(ch!='#') ? arr[++i] : ch;
}
}
GetTop(s1,&w);
while(w!='#')
{
jisuan(pop(&s1),&s2);
GetTop(s1,&w);
}
return Dpop(&s2);
}
/*主函数*/
void main()
{
char str[100];
char *yzh;
printf("Please input the infix express with a '#' in the end :");/*输入表达式并以#号结束*/
gets(str);
yzh=str;
printf("The infix express is:%s/n",yzh);
printf("/nThe result is:%f/n/n",comp(str));
}
相关文章推荐
- 利用栈来实现计算表达式的自动计算(一)
- 完全利用栈实现表达式的计算问题
- 利用API 实现字符串表达式的计算
- 利用二叉树实现表达式计算
- VB利用堆栈实现表达式计算
- 利用API 实现字符串表达式的计算
- 利用数组模拟栈实现简单的表达式中缀转后缀并进行计算
- 《利用栈实现含浮点数的算术表达式的计算》
- C#利用js脚本实现配置的文本表达式计算
- 利用jQuery实现购物车自动计算总金额
- 利用DataTable的表达式列完成自动计算列值
- Web报表中用switchCase实现不同条件自动计算不同的表达式
- C#中利用正则表达式实现字符串搜索
- 利用java反射机制实现javaweb自动调用类的方法
- [转载]利用Web Services实现软件自动升级
- 利用ORACLE存储过程与JOB结合实现对数据表自动备份
- 利用Modem自动应答实现远程串口通讯
- 利用Cookie实现自动登录,尽量做到安全
- 利用数组模拟数字,实现计算大数字阶乘00
- 利用深度学习网络自动给图像上色的文章和相关工程实现