逆波兰计算(简单叙述):
在计算一个数学式子时,如计算(3-2)+6*(2+3)时,按照我们一般的思路会优先计算括号内的算式,在计算乘法(算的快的伙伴可以同时计算)最后在将+两边的结果相加得到一个新的数值。
如果将这么一个数值进行计算的话,我们需要向判断是否有括号,是大括号、中括号、小括号还是乘和除,因此通过栈等方式就需要花费很长的时间在判断计算顺序上。
因此,我们就需要一个相对快捷的方式去进行计算。由此,我们就可以使用逆波兰来进行简化程序的计算过程。
根据上述提到的表达式,我们的逆波兰表达式可以写成:3 2 - 2 3 + 6 * +
看起来很不顺眼,但是他对我们使用栈来计算会非常的友好,我们可以来简单分析一下:
1、3 2 -先输入3 2,遇到“-”就对 3 2 进行减计算,存储到base(栈的最底层);
2、2 3 +输入2 3,遇到 “+”就对 2 3进行加计算,存储到base+1;
3、输入6 * ,遇到“ * ”计算6 * (2+3),存储到base+1;
4、输入 + ,遇到 “ + ”,计算base 和base +1 所存储的数据,对他们进行相加,输出最终结果。
接下来就根据步骤来进行编程。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 10
typedef double ElemType;
typedef struct
{
ElemType *base;
ElemType *top;
int stackSize;
}sqStack;
//创建一个栈
void InitStack(sqStack *s)
{
s->base = (ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(!s->base)
exit(0);
s->top = s->base;
s->stackSize = STACK_INIT_SIZE;
}
void Push(sqStack *s,ElemType e)
{
if(s->top - s->base >= s->stackSize)
{
s->base = (ElemType *)realloc(s->base,(s->stackSize+STACKINCREMENT)*sizeof(ElemType));
if(!s->base)
exit(0);
*(s->top)=e;
s->top++;
}
}
void Pop(sqStack *s,ElemType *e)
{
if(s->top == s->base)
{
return ;
}
*e = *--(s->top);
}
int StackLen(sqStack s)
{
return (s.top-s.base);
}
int main()
{
sqStack s;
char c;
double d,e;
char str[MAXBUFFER];
int i=0;
InitStack(&s);
printf("请按逆波兰表达式输入带计算数据,数据与运算符之间用空格隔开,以#作为结束标志:\n");
scanf("%c",&c);
while(c!='#')
{
while(isdigit(c)||c=='.')
{
str[i++]=c;
str[i]='\0';
if(i>=10)
{
printf("出错:输入的单个数据过大!\n");
return -1;
}
scanf("%c",&c);
if(c==' ')
{
d = atof(str);
Push(&s,e);
i=0;
break;
}
}
switch(c)
{
case '+':
printf("栈长:%d",StackLen(s));
Pop(&s,&e);
Pop(&s,&d);
printf("栈长:%d",StackLen(s));
Push(&s,d+e);
break;
case '-':
Pop(&s,&e);
Pop(&s,&d);
Push(&s,d-e);
break;
case '*':
Pop(&s,&e);
Pop(&s,&d);
Push(&s,d*e);
break;
case '/':
Pop(&s,&e);
Pop(&s,&d);
if(e!=0.0)
{
Push(&s,d/e);
}
else
{
printf("\n出错:除数为0!");
return -1;
}
break;
}
scanf("%c",&c);
}
Pop(&s,&d);
printf("\n最终的计算结果是:%.lf",d);
return 0;
}
(仅供参考,如有问题,可私信)