数据结构与算法--1.1栈(后缀表达式计算)

一般的后缀表达式(也叫逆波兰表达式),要想计算这样的表达式,可以利用到栈。

1.栈的逻辑和1.栈 博客是一样的

2.计算方法及代码

2.1先接受输入一个字符,在while循环判断结束标志 ‘#’,在循环中继续接受输入下一个字符

2.1 对数字字符和计算符号字符分别的处理。

对于计算符号,用switch 分别对+-*/ 进行分类,遇到输入的字符是计算符号, 先将两个栈的数据pop出栈,将出栈的两个数据,进行+-*/的计算

对于数字字符,用isdigit函数判断字符是否是数字,或者字符是否带小数点。因此我们设置了一个字符数组缓冲区str[MAXBUFFER],用来接收数字字符。之后将str[MAXBUFFER]用atof函数转换为double类型的数据,将该double类型的数据push入栈

// 栈-后缀表达式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS  //为了避免scanf函数报错
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define InitSize 20
#define IncrementSize 10
#define MAXBUFFER 10
typedef double ElimentType;
typedef struct
{
    ElimentType* top;
    ElimentType* base;
    int StackSize;
}sqStack;

void InitStack(sqStack* s)
{
    s->base = (ElimentType*)malloc(InitSize * sizeof(ElimentType));
    if (!s->base)
    {
        exit(0);
    }
    s->top = s->base;
    s->StackSize = InitSize;
}void Push(sqStack* s, ElimentType c)
{
    if (s->top - s->base >= s->StackSize)
    {
        s->base = (ElimentType*)realloc(s->base, (s->StackSize + IncrementSize) * sizeof(ElimentType));
        if (!s->base)
        {
            exit(0);
        }
        s->top = s->base + s->StackSize;
        s->StackSize = s->StackSize + IncrementSize;
    }
    *(s->top) = c;
    s->top++;
}
void Pop(sqStack* s, ElimentType* c)
{
    if (s->top == s->base)
    {
        return;
    }
    s->top--;
    *c = *(s->top);
}
int Stacklen(sqStack s)
{
    int len = 0;
    len = s.top - s.base;
    return len;
}


int main()
{
    sqStack s;
    InitStack(&s);
    char c, d;
    double e,f,g;
    char str[MAXBUFFER];
    int t=0;
    printf("请输入一个波兰表达式,数字之间,运算符之间以空格隔开,最后表达式以#号结束\n");
    scanf("%c", &c);
    while(c != '#')
    {
        while (isdigit(c) || c == '.') //判断字符是否为数字和小数点  ,对字符进行处理
        {
            //做一个缓冲区
            str[t++] = c;
            str[t] = '\0';
            if (t >= 10)
            {
                printf("error:the single data is too larger to contain!");
                return -1;
            }
            scanf("%c", &c);
            if (c == ' ')
            {
                g = atof(str);//把char数组转化为double
                Push(&s, g); //把转化成double类型的g入栈
                t = 0; //t置零,用于下次缓冲
                break;
            }

        }
        switch (c)  //对运算符进行分类计算
        {
            case '+'://如果是+,先将栈的两个数据pop出栈,将+计算后的结果push入栈
                Pop(&s, &e);
                Pop(&s, &f);
                Push(&s, f + e);
                break;
            case '-':
                Pop(&s, &e);
                Pop(&s, &f);
                Push(&s, f - e);
                break;
            case '*':
                Pop(&s, &e);
                Pop(&s, &f);
                Push(&s, f * e);
                break;
            case '/':
                Pop(&s, &e);
                Pop(&s, &f);
                if (e != 0)
                {
                    Push(&s, f / e);
                }
                else {
                    printf("error: the number should not be a zero !");
                    return -1;
                }
                break;
        }
        scanf("%c", &c);   //在循环中不断的输入字符

    }
    Pop(&s, &g);
    printf("the final result is %f.\n", g);


    return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

输入后缀表达式  1 10 + 5 * 1 / #

输出结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值