利用栈的特性实现逆波兰表达式的运算(无括号)

本文探讨了逆波兰表达式,一种由J・卢卡西维兹提出的后缀表达式。主要内容聚焦于不含括号的逆波兰表达式的运算,通过C语言实现相关算法,利用栈的数据结构进行计算。
摘要由CSDN通过智能技术生成

百度原文:
逆波兰表达式又叫做后缀表达式。逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法 。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。
在这里插入图片描述
这篇博客先讲 没有括号的 逆波兰表达式运算
实现代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<ctype.h>//isdigit()头文件
#define  size 20
#define create 10
struct list
{
 double *base;
 double *top;
 int stacksize;

};
void INistack(  list *s)//初始化栈 
{
s->base=(double *) malloc(size *sizeof(double));// 为栈分配20 * double 大小的内存 
if(!s->base)//分配失败
{
exit(0);
}
s->top=s->base;
s->stacksize=size;
}

void ya(list *s ,double e)
{ if(s->top -s->base>=s->stacksize) //空间不够
{
 s->base =(double *)realloc(s->base,(s->stacksize+create * sizeof(double ))); //从新给base  赋值空间 (多出10个double的空间)
 if(!s->base)
 exit(0);
  s->stacksize=s->stacksize+size;
 s->top=s->base + s->stacksize;//bsae 新偏移的位置作为栈顶

}
*(s->top)=e; //从栈底 存数据,存完上移 注意, 刚开始 这里栈底等于栈顶
s->top++;

}

void chu(list *s, double * e)
{ if(s->top==s->base)
{return ; 
}
*e=*--(s->top); //出栈,栈顶下移,因为栈顶不存数据 所以是-- 后 取值
}

 int stacklength(list s)
 {
 return (s.top-s.base); // 元素个数
 }
 int main()
 { char c;
 double d,e; //计算的值可能是浮点型的,所以要double

list s;
int i=0;

INistack(&s);//初始化栈
char str[10]; //如果有小数点

 printf("请输入逆波兰表达式数字用空格隔开,输入#表示结束!\n");
 scanf("%c",&c);
while(c!='#')
{ 
	while(isdigit(c)||c=='.') // isdigit 函数可以 判断char 类型的是否对应 整数型的 0 到 9  || '.'是为了 小数之后仍然操作  
{
  str[i++]=c;
  str[i]='\0';
  if(i>=10)//数据不能太大 否则报错
  {
   printf("出错了,输入数据过大\n");
	   return -1;
  } //遇到空格 跳转到下一行代码
  scanf("%c",&c);//如果 是%c 就可以接受 空格 ,而不是跳过 但是 如果 是%d的话 就不会接受空格
  if(c==' ')
  {
  d=atof(str);// atof(char * ) 可以将字符串转换成浮点型数 所使用的头文件为<stdlib.h>
  ya(&s,d);//转换成浮点数成功了就把它存入占中 或者说,压入栈中
  i=0;//这里每次都要 让I等于 0 方便下次存取 又从第一个 字符数组下标 开始存起
  break;

  }
}
switch(c) //遇到符号
{ 
case '+' :
  chu(&s,&e); //出栈第一个
  chu(&s,&d);//出栈第两个
  ya(&s,d+e);//把结果压入栈中
 break;
case '-':
	 chu(&s, &e);
	chu(&s,&d);
	 ya(&s,d-e);
	 break;
case '*':
		 chu(&s,&e);
		 chu(&s,&d);
		 ya(&s,d*e);
		 break;
case '/':
			 chu(&s,&e);
			 chu(&s,&d);
			 if(e!=0)
			 {
			 ya(&s,d/e);
			 }
			 else
			 {
			 printf("\n出错了,除数为零!\n");
			 return -1;
			 }
				break;
  
}
 scanf("%c",&c); //再读入一个数 如果是#就结束,否则 继续循环

}
chu(&s,&d); //计算到最后 肯定只剩下一个结果 ,然后把这个结果 输出来  (前提 是两个 数字匹配 一个符号);
printf("最终结果为 : %f \n",d);
 return 0;
 }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是牛大春呀

老板糊涂啊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值