注册 登录
编程论坛 数据结构与算法

[原创]算术表达式求值演示

starrysky 发布于 2005-11-24 11:14, 15466 次点击


我的一个同学找我搞定数据结构的实验报告,因为只有2天的时间,我就胡乱做了个。
下面是运行后生成的应用程序,给大家看看效果。(开始发的那个运行太快,看不见,请重新下载)
这是按照《数据结构习题集》严蔚敏版的实验2.5做的。
至于完整源代码,我下个星期5以后再发出来(呵呵,一点私心,防止上交的报告中有重复的)。
这里把关键的函数发出来。

int power(char x,int &base)// base用来保证括号内运算权限比括号外高(最关键的地方,运算符的权值设定)
{
int power;
if(x=='+'||x=='-')
power=base+1;
if(x=='*'||x=='/')
power=base+2;
if(x=='(')
{
power=3;
base+=3;
}
if(x==')')
{
power=-1;
base+=3;
}
if('0'<=x&&x<='9')
power=0;
}


void guocheng(char *infix)//整个算术表达式运算的过程,请在适当位置自行添加显示OPTR,OPND栈中内容和操作的函数(现在这个函数相当于算法)
{
int a,b,c,base=0,i;
char x,y;

for (i = 0; infix[i] != '\0'; i++)
{
x=infix[i];
if (power(x)==0)//数字就入栈
{
a=x-'0';
push(opnd,a);
}
else if(power(x)==3)// 遇到'('就进栈
{
push(optr,c);
}
else if (power(x)==-1)//')',运算消除一对()
{
a=pop(opnd);
b=pop(opnd);
y=pop(optr);
c=math(b,y,a);
push(opnd,c);
y=pop(optr);
if(y=='('); //考虑如3+5*(3+5*6)
else
{
a=pop(opnd);
b=pop(opnd);
c=math(b,y,a);
push(opnd,c);
pop(optr);
}

}
else
{
if(power(x)>power(top(optr))) //如果运算符权值打于栈顶元素的权值,就入栈
push(optr,x);
else //权值相同情况下就先计算前面的。
{
a=pop(opnd);
b=pop(opnd);
y=pop(optr);
c=math(b,y,a);
push(opnd,c);
push(optr,x);
}
}
}//for
y=pop(optr);
while(y)
{
a=pop(opnd);
b=pop(opnd);
c=math(b,y,a);
push(opnd,c);
y=pop(optr);
}
}


只有本站会员才能查看附件,请 登录
这个是老版本了,只有一个可执行文件,请到第3楼下载新版本,有原代码

[此贴子已经被作者于2006-4-25 10:46:35编辑过]

35 回复
#2
starrysky2005-11-24 11:28
说明一下,像2*2(1+1)这样数子后面直接接'('的表达式非法,12+1这种数字超过了9的表达式非法
#3
starrysky2005-12-25 13:27
只有本站会员才能查看附件,请 登录

[此贴子已经被作者于2006-4-27 19:10:48编辑过]

#4
starrysky2005-12-25 13:34

前几天忙着考试去了,没有按时发上来,不好意思啊。

#5
muyilion2005-12-27 19:08

谢了,赞一个!

#6
starrysky2006-01-13 11:59



看过或用过的朋友给 个意见啊,看看这个程序有什么BUG或不足啊?我好改进。
希望各位不吝赐教啊

#7
shenjun2006-03-06 17:52

你好,有没有详细的程序啊!!急用^^^^^^^^^^^

#8
shenjun2006-03-06 18:00
哦 ,不好意思,刚才没看见,谢谢!!!
#9
poster2142006-04-24 09:48

谢谢分享

#10
xiao_pig2006-04-27 18:40

我也写了一个,支持float型数字……
//建立栈类模板,在主函数中创建两个模板实例


#include<process.h>
#include<string.h>
#define MAX_SIZE 100

template<class T>class Stack
{
T data[MAX_SIZE];
int top;

public:

Stack(void);
~Stack(void);
bool empty(void);
void push(T a);
T pop(void);
T GetTop(void);
};

template <class T>Stack<T>::Stack(void)//构造函数
{
top=-1;
}

template <class T>Stack<T>::~Stack(void)//析构函数
{
}

template <class T>bool Stack<T>::empty(void)//判断栈空操作
{
return top==-1?true :false;
}
template <class T>void Stack<T>::push(T a)//入栈操作
{
if(top==MAX_SIZE)
{
cout<<"Stack is full!"<<endl;
return;
}

data[++top]=a;
}

template <class T>T Stack<T>::pop(void)//出栈操作
{
if(top==-1)
{
cout<<"Stack is underflow!"<<endl;
return 0;
}
return data[top--];
}
template <class T>T Stack<T>::GetTop(void)//取栈头元素操作
{
if(top!=-1)
return data[top];
else return false;
}
//计算表达式求值过程演示


#include<iostream.h>
#include<stdio.h>
#include<math.h>
#include"tstack.h"

float Operate(float a,char theta,float b)
{
float s;
switch(theta)
{
case'+': s=a+b;break;
case'-': s=a-b;break;
case'*': s=a*b;break;
case'/': s=a/b;break;
}
return s;
}


char Precede(char a,char b)
{
char array[7][7]={'>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>','>','<','>','>','>','>','>','>','<','>','>','<','<','<','<','<','=','0','>','>','>','>','0','>','>','<','<','<','<','<','0','='};

int i,j;

switch(a)
{
case'+': i=0;break;
case'-': i=1;break;
case'*': i=2;break;
case'/': i=3;break;
case'(': i=4;break;
case')': i=5;break;
case'#': i=6;break;
}

switch(b)
{
case'+': j=0;break;
case'-': j=1;break;
case'*': j=2;break;
case'/': j=3;break;
case'(': j=4;break;
case')': j=5;break;
case'#': j=6;break;
}

return(array[i][j]);
}

void main()
{
char array[100],x,theta;
char *p,*q,A='y';
float s;
int i;
float v=0.0,a=0.0,b=0.0;
cout<<'\t'<<'\t'<<"****************************************"<<endl;
cout<<'\t'<<'\t'<<" 算术表达式求值 "<<endl;
cout<<'\t'<<'\t'<<"****************************************"<<endl;
cout<<'\t'<<'\t'<<" ------------中国科技大学-------------- "<<endl;
cout<<'\t'<<'\t'<<"|作者: 老大的小猪 |"<<endl;
cout<<'\t'<<'\t'<<"|______________________________________|"<<endl;

while(A=='y')
{
cout<<"请输入表达式(以#号键结束):"<<endl;
p=array;
cin>>array;

Stack<char>OPTR;
Stack<float>OPND;

OPTR.push('#');

while((*p)!='#'||OPTR.GetTop()!='#')
{
if((*p)>='0'&&(*p)<='9')
{
v=0.0;
q=p;
i=-1;
while((*q)>='0'&&(*q)<='9'&&(*q)!='.')
{
i++;
q++;
}


for(;i>=0;i--)
{
s=pow(10,i);
v+=((*p)-'0')*s;
p++;
}

if((*p)=='.')
{
p++;
while((*p)>='0'&&(*p)<='9')
{
s=pow(10,i);
v+=((*p)-'0')*s;
i--;
p++;
}
}
OPND.push(v);
}
else
switch(Precede(OPTR.GetTop(),(*p)))
{
case '<':OPTR.push((*p));
p++;break;
case '=':x=OPTR.pop();
p++;break;
case '>':theta=OPTR.pop();
b=OPND.pop();
a=OPND.pop();
OPND.push(Operate(a,theta,b));
break;
}
}
printf("%f\n",OPND.GetTop());
cout<<"想继续吗(y/n)?";
cin>>A;
}


}


#11
starrysky2006-04-27 18:54
哈哈,不错不错,很有意思,待我下去好好研究下

顺便给个楼上的程序下载网页连接(EXE文件,没有原代码,原代码在楼上), 方便大家学习鉴赏
https://www.bc-cn.net/bbs/dispbbs.asp?boardID=179&ID=60661&page=1

[此贴子已经被作者于2006-4-27 18:57:26编辑过]

#12
激情依旧2006-04-29 11:35

强烈支持starrysky啊。。。。。数据结构版幸亏还有你在

#13
starrysky2006-04-29 12:02

哇,给我扣了顶这么大的帽子,想不努力都不行啊.
欢迎回来, 激情!
这次怎么也该在静老大的数据结构历届斑竹名录里面留个名吧,不然就说不过去了啊, 你看热情都上榜n次了.

[此贴子已经被作者于2006-4-29 21:15:55编辑过]

#14
pniyik2006-05-06 09:44

顶,我们老师快下最后的通牒了.
幸好找到了你们

#15
jusdin2006-06-08 22:04

顶一个先~``
楼主有QQ么?
有些问题想请教啊~~

#16
乌鸦丘比特2006-06-09 08:29

这个问题可以推广,比如加上乘方运算的表达式求值

#17
dreamsdeng2006-06-20 00:36

最近课程设计,刚好要做这个题目,谢谢啦~~^_^

#18
xinghui2006-06-21 00:25

嘿嘿,楼主,谢谢了。
我可以好好研究一下了。。。

#19
HELLO02006-06-22 15:48

我下载了,但在TC上不能运行

请问是什么原因

#20
方方2006-06-29 13:22

程序运行的时候,如果输入错误的表达式,但是它还是会继续运行.

#21
冰雨2006-06-29 20:55

喜欢。。。。
#22
starrysky2006-07-01 20:19
以下是引用方方在2006-6-29 13:22:00的发言:

程序运行的时候,如果输入错误的表达式,但是它还是会继续运行.

是的,即使是错误的表达式也会把它的入栈出栈顺序表示出来,但计算的结果是错的

#23
sll2006-07-03 11:36

不错哦!!!!!!!!

#24
Zacard2006-07-07 18:47

不错,但是比不上我的
我也做这个
我的能实现实数运算,
你的好像不能处理大于10的数
569912111

#25
mnzmx2006-07-07 20:02

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAXNUM 100

char top(char a[])
{
int i;
char b;
for(i=0;a[i]!='\0';i++);

b=a[i-1];
return b;
}

int power(char x,int &base)
{
int power;
if(x=='+'||x=='-')
power=base+1;
if(x=='*'||x=='/')
power=base+2;
if(x=='(')
{
power=3;
base+=3;
}
if(x==')')
{
power=-1;

}
if('0'<=x&&x<='9')
power=0;
return power;
}

int pop1(int a[])
{
int i,b;
for(i=0;a[i];i++);//!='\0'

b=a[i-1];
a[i-1]='\0';
return b;
}
char pop2(char a[])
{
int i;
char b;
for(i=0;a[i]!='\0';i++);

b=a[i-1];
a[i-1]='\0';
return b;
}
int math(int x,char y,int z)
{
if (y=='+')
x=x+z;
if (y=='-')
x=x-z;
if (y=='*')
x=x*z;
if (y=='/')
x=x/z;
return x;
}

void push1(int a[],int b)
{
int i;
for(i=0;a[i];i++);

a[i]=b;
a[i+1]='\0';
}
void push2(char a[],char b)
{
int i;
for(i=0;a[i]!='\0';i++);

a[i]=b;
a[i+1]='\0';
}


void infixtoSuffix(const char *infix)
{
int i,b,c,base=0,opnd[MAXNUM],m,a;
char y,x,optr[MAXNUM];
opnd[0]='\0';
optr[0]='\0';
for (i = 0; infix[i] != '\0'; i++)
{
x=infix[i];
if (power(x,base)==0)
{
if (i>0&&power(infix[i-1],base)==0)
{
b=pop1(opnd);
a=10*b+int(x-'0');
}
else
a=int(x-'0');//
push1(opnd,a);

for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s%-10c%d入OPND栈\n", optr, x, a);

}
else if (power(x,base)==-1)
{

a=pop1(opnd);
b=pop1(opnd);
y=pop2(optr);
c=math(b,y,a);
push1(opnd,c);
////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s%-10c计算%d%c%d并将结果%d压入OPND栈\n", optr, x,b, y,a,c);

//////////////////////////////////


y=pop2(optr);
///////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s %c出OPTR栈\n", optr, y);
/////////////////////////////////


if(y=='(') ;
else
{

while(y!='(')
{
a=pop1(opnd);
b=pop1(opnd);
c=math(b,y,a);
push1(opnd,c);
//////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s 计算%d%c%d并将结果%d压入OPND栈\n", optr, b, y,a,c);
///////////////////////////////////

y= pop2(optr);
}
////////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s %c出OPTR栈\n", optr, y);
//////////////////////////////////
}
base-=3;
}
else if (power(x,base)==3)
{
push2(optr,x);
///////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s%-10c%c入OPTR栈\n", optr, x, x);

}
else
{
if(power(x,base)>power(top(optr),base))
{push2(optr,x);
///////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s%-10c%c入OPTR栈\n", optr, x, x);
///////////////////////////
}
else
{
a=pop1(opnd);

b=pop1(opnd);

y=pop2(optr);

c=math(b,y,a);

push1(opnd,c);
/////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(m;m!=0;m--)
printf(" ");
printf("%-15s%-10c计算%d%c%d并将结果%d压入OPND栈\n", optr, x ,b, y,a,c);
///////////////////////////////////
push2(optr,x);
/////////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(;m!=0;m--)
printf(" ");
printf("%-15s%-10c%c入OPTR栈\n", optr, x, x);
///////////////////////////////
}
}
}
y=pop2(optr);

while(opnd[1]!='\0')
{
a=pop1(opnd);

b=pop1(opnd);

c=math(b,y,a);

push1(opnd,c);
//////////////////////////////////
for(m=0;opnd[m];m++)
printf("%d ", opnd[m]);
m=10-m;
for(;m!=0;m--)
printf(" ");
printf("%-15s 计算%d%c%d并将结果%d压入OPND栈\n", optr, b, y,a,c);
//////////////////////////////
y=pop2(optr);
}
printf("算术表达式计算结果为:%d\n",opnd[0]);

}


void getline(char *line, int limit)
{
char c;
int i=0;
while (i<limit-1&&(c=getchar())!=EOF&&c!='\n')
line[i++]=c;
line[i]='\0';
}

void main()
{
char infix[MAXNUM] ;
printf(" ***********************************\n");
printf(" * 算术表达式求值演示 *\n");
printf(" * --------------------------- *\n");
printf(" * 制 作 人 starrysky *\n");
printf(" * 个人信息 见论坛简介 *\n");
printf(" * QQ 297456458 *\n");
printf(" * ————————————————*\n");
printf(" ***********************************\n");
printf("\n\n说明:\n如下表达式非法:\n 数字和'('直接连接在一起,如 1+2(1+1)\n 请输入一个表达式,如3*(7-2)。\n\n请输入表达式 :");
getline(infix, MAXNUM);
printf("\n");
printf("OPND栈 OPTR栈 输入字符 主要操作\n");
infixtoSuffix(infix);
printf("按回车结束。");
getchar();

}

在WIN-TC下编译会说int power(char x,int &base)这句“说明语法错误”??????

#26
mnzmx2006-07-07 20:36
我用C++bulder编译后可以运行,但是运算结果会出错误有一个莫名其妙的数会进栈
#27
starrysky2006-07-09 15:15
以下是引用Zacard在2006-7-7 18:47:00的发言:

不错,但是比不上我的
我也做这个
我的能实现实数运算,
你的好像不能处理大于10的数
569912111

谁说不能处理大于10的数啊,楼顶的老版本好象是不行,但后面的新版本100*100 都可以,不过我设定的变量类型为int , 所以最好计算时不要溢出,否则计算结果能显示,但结果是错的。

#28
starrysky2006-07-09 15:20
以下是引用mnzmx在2006-7-7 20:02:00的发言:

在WIN-TC下编译会说int power(char x,int &base)这句“说明语法错误”??????

SunShine 过来帮忙看看,我现在在网吧上网,自己电脑前几天格式化了一次,没装WIN-TC。

#29
starrysky2006-07-09 15:23
以下是引用mnzmx在2006-7-7 20:36:00的发言:
我用C++bulder编译后可以运行,但是运算结果会出错误有一个莫名其妙的数会进栈

现在我电脑上没有C++Build , 等明天我装个后看看。

这个程序是在VC++6.0下编译通过的。用其他的编译器可能会出现问题(我没用其他编译器试过)。

#30
Firedy2006-10-10 18:38

十分感谢

#31
taomb2006-10-11 16:40

晕了

#32
Love嵌入式2008-04-12 12:26
厉害啊!!
#33
GZH2008-12-07 16:16
谢了,赞一个!
#34
2010-05-06 17:57
能不能解释一下,看不懂
#35
阝子健2011-07-06 23:56
好耶 太好了
#36
碧海潮生2011-11-22 21:37
太好了急需
1