C语言数据结构-计算逆波兰表达式(小数值版)

        逆波兰表达式的计算通常采用栈实现,这里我们使用链栈,逆波兰表达式用字符数组存储,实现起来也是很简单的,我们依次遍历逆波兰表达式的每一个字符,当遇到数字就入栈,否则就进行计算,计算之前先从栈中取出两个数字,进行四则运算,计算完成后结果入栈。在C语言中整形和字符型的转换有个很巧妙的技巧,但数值计算结果要求在0-9之间,否则转换时没有对应的ASCII值便会出错,我们在下面四则运算时将会使用到!当然你也可以用一些标准库函数atoi,atol,atof函数这些进行转换,可以完成其他绝大部分计算(受计算机精度影响)。

        例如:'5'转5,5转'5'

                char转int        '5'-'0'=5 

                int转char         5+'0'='5'

        原理:

        1.两个char型相减得到的是他们的差值,这个差值正好是整型因为C语言使用的是字符对应的ASCII值进行计算,我们减字符'0'正好得到的是该字符对应的整型数值

        2.一个int型与一个char型相加,运算结果为char型的ASCII值+int型的数值(这里整型用的是它自己的数值大小没有使用整型的ASCII值进行运算)计算出来的ASCII值正好对应结果的数字字符

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define Status int
#define OK 1
#define Error 0
#define OVERFLOW 1

// 定义栈的结构体
typedef struct Stack {
    char Element;         // 栈元素
    struct Stack* next;   // 指向下一个栈元素的指针
} Stack;

// 初始化栈
Status InitStack(Stack* Head) {
    Head = (Stack*)malloc(sizeof(Stack)); // 分配内存给栈头节点
    if (!Head) exit(OVERFLOW);            // 如果内存分配失败,退出程序
    Head->next = NULL;                    // 初始化栈为空
    return OK;
}

// 获取栈顶元素
Status GetTop(Stack Head, char* e) {
    if (!Head.next) return Error;         // 如果栈为空,返回错误
    *e = Head.next->Element;             // 获取栈顶元素
    return OK;
}

// 入栈操作
Status Push(Stack* Head, char e) {
    if (!Head) return Error;              // 如果栈头指针无效,返回错误
    Stack* p = (Stack*)malloc(sizeof(Stack)); // 分配内存给新栈元素
    if (!p) return OVERFLOW;             // 如果内存分配失败,返回溢出
    p->Element = e;                      // 设置栈元素值
    p->next = Head->next;               // 将新节点的 next 指针指向原栈顶
    Head->next = p;                     // 更新栈头指针的 next 指向新节点
    return OK;
}

// 出栈操作
Status Pop(Stack* Head) {
    if (!Head) return Error;             // 如果栈头指针无效,返回错误
    if (!Head->next) return Error;      // 如果栈为空,返回错误
    Stack* p = Head->next;              // 获取栈顶元素
    Head->next = p->next;               // 更新栈头指针的 next 指向原栈顶的下一个元素
    free(p);                            // 释放栈顶元素的内存
    return OK;
}

int main() {
    Stack stack;                        // 创建栈实例
    InitStack(&stack);   // 初始化栈
    char str[] = { '5', '2', '-', '4', '*', '\0' }; // 逆波兰表达式,原始中缀表达式为:(5-2)*4
    // 遍历逆波兰表达式
    for (int i = 0; i < strlen(str); i++) {
        // 如果遇到运算符
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
            char num1, num2;
            GetTop(stack, &num1);  // 获取栈顶元素
            Pop(&stack);           // 出栈
            GetTop(stack, &num2);  // 获取新的栈顶元素
            Pop(&stack);           // 出栈

            // 执行相应的运算,并将结果入栈
            if (str[i] == '+') Push(&stack, ((num2 - '0') + (num1 - '0')) + '0');
            if (str[i] == '-') Push(&stack, ((num2 - '0') - (num1 - '0')) + '0');
            if (str[i] == '*') Push(&stack, ((num2 - '0') * (num1 - '0')) + '0');
            if (str[i] == '/') Push(&stack, ((num2 - '0') / (num1 - '0')) + '0');
        }
        else {
            Push(&stack, str[i]);  // 如果是数字,则直接入栈
        }
    }

    char result;
    GetTop(stack, &result);  // 获取最终计算结果
    Pop(&stack);             // 出栈结果

    // 打印逆波兰式
    printf("逆波兰式为: ");
    for (int i = 0; i < strlen(str); i++) {
        printf("%c", str[i]);
    }
    printf("\n计算的结果为: %d\n", result - '0');  // 打印计算结果

    return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值