逆波兰表达式

逆波兰表达式也叫后缀表达式
下式为转换成逆波兰表达式
( 1 - 2 )*( 4 + 5 )—> 1 2 - 4 5 + *

那么逆波兰表达式对于栈的意义在哪里呢?

当然是简化操作步骤,正常来说计算机进行这种带括号的运算需要先算括号里面的,再算括号外面的,而逆波兰表达式则只需要顺序操作即可,不需要反复操作。

这就取得了空间与时间的优势。

逆波兰表达式的运算过程。

即遇到符号则推出。

就针对1 2 - 4 5 + * 来说,先将1 2 进栈,然后遇到 - ,就将1 2 出栈进行运算,将结果压栈,然后压入4 5 +,遇到 + ,将4 5 出栈运算,将结果压栈,遇到 * 将剩余结果出栈计算

//逆波兰表达式计算器
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 20
#define STACKINCREMENT  10
#define MAXBUFFER       10

typedef double ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;
    int stackSize;
}sqStack;

InitStack(sqStack *s)
//当函数返回值为int型时,可以不写函数类型,如果不是,就得写。
{
    s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if( !s->base )
        exit(0);
    s->top = s->base;
    s->stackSize = STACKINCREMENT;
}

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 = s->base + s->stackSize;
      s->stackSize = s->stackSize + STACKINCREMENT ;
      }
      *(s->top) = e;
      s->top++;
}

Pop(sqStack *s , ElemType *e)
{
    if(s->top == s->base)
        return -2;
    (*e) = *--(s->top);    
}

int StackLen(sqStack s)
{
    return(s.top - s.base );
}

int main()
{
    sqStack s;
    char c;
    char str[MAXBUFFER];
    double e,d;
    int i = 0;
    InitStack( &s );
    printf("请按逆波兰表达式输入输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志");
    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);
	        //功能是把字符串转换成浮点数,所使用的头文件为<stdlib.h>
	        Push(&s , d);//将数字压入栈
	        i = 0;
	       //初始化i,此后相当于重置str[0]
	        break;
	    }
	    
   	}

        switch( c )
        {
            case ' + ':
            Pop( &s , &d );
            Pop( &s , &e );
            Push(&s , d + e );
            break;
            case '-':
            Pop( &s , &d );
            Pop( &s , &e );
            Push(&s , e - d );
            break;;
            case ' * ':
            Pop( &s , &d );
            Pop( &s , &e );
            Push(&s , d * e );
            break;
            case' / ':
            Pop( &s , &d );
            Pop( &s , &e );
            if( e != 0 )
            {
            Push(&s , e / d );
            }
            else
            {
            printf("除数为零,错误");
            }
            break;            
        }
        scanf("%c",&c);//从缓冲区的第三次获取
    }
    Pop(&s , &d);
    printf("最终的计算结果为%f",d);
    return 0;
}                   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值