C语言学习笔记20260703-牛牛与后缀表达式(逆波兰表达式)

C语言学习笔记20260703-牛牛与后缀表达式(逆波兰表达式)

1. 题目概述

本题要求计算一个特定格式的后缀表达式的值。

  • 输入格式 :字符串 s,数字以 # 结尾作为分隔符,运算符为 +、-、*。
  • 示例 :12#3#+15#* 中缀形式 (12+3)*15 结果 225。
  • 数据范围 :字符串长度可达 10610^6106,运算结果绝对值不超过 101810^{18}1018(需使用 long long)。

2. 核心知识点:栈的应用

后缀表达式(又称逆波兰表达式)是计算机科学中经典的**栈(Stack)**应用场景。其求值过程不需要考虑运算符优先级或括号,算法逻辑非常直接。

算法流程

从左到右扫描表达式字符串:

  1. 遇到数字:解析出完整的数值,将其压入栈中。
  2. 遇到运算符 :
    • 从栈顶弹出两个元素。
    • 注意顺序 :先弹出的是右操作数 ,后弹出的是左操作数。
    • 执行运算,将结果压回栈中。
  3. 结束:扫描完成后,栈中剩下的唯一元素即为最终结果。

⚠️ 易错点 :减法和除法不满足交换律。若栈中元素为 [a, b](b在栈顶),遇到 - 时,应计算 a - b,而非 b - a。


3. 代码实现与解析

以下是基于 C 语言的数组模拟栈解法:

c 复制代码
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 给定一个后缀表达式,返回它的结果
 * @param str string字符串 
 * @return long长整型
 */
long long legalExp(char* str) 
{
    // 定义足够大的数组模拟栈,防止溢出
    const int MAXN = 1000005;
    long long stack[MAXN];
    
    // top 指向栈顶元素的下一个位置(即当前栈内元素个数)
    int top = 0;
    int len = strlen(str);
    long long num = 0; // 用于暂存正在拼接的数字

    for(int i = 0; i < len; i++)
    {
        char c = str[i];
        
        // 1. 处理数字字符
        if(c >= '0' && c <= '9')
        {
            // 累加构建多位数 (例如 "12" -> 1*10 + 2)
            num = num * 10 + (c - '0');
        }
        // 2. 处理数字结束标志 '#'
        else if(c == '#')
        {
            // 将构建好的数字入栈
            stack[top++] = num;
            num = 0; // 重置数字缓存
        }
        // 3. 处理运算符
        else if(c == '+' || c == '-' || c == '*')
        {
            // 取出右操作数(栈顶)
            long long b = stack[--top];
            // 取出左操作数(新栈顶)
            long long a = stack[--top];
            
            long long res;
            switch(c)
            {
                case '+': res = a + b; break;
                case '-': res = a - b; break; // 注意是 a - b
                case '*': res = a * b; break;
                default:  res = 0;
            }
            
            // 将运算结果压回栈中
            stack[top++] = res;
        }
    }
    
    // 最终栈顶元素即为结果,top指向栈顶元素的下一个位置(即当前栈内元素个数)
    return stack[top - 1];
}

关键细节分析

  1. 多位数的处理 :

    题目中数字可能不止一位(如 12)。代码中使用变量 num 进行累加 (num = num * 10 + ...),直到遇到 # 才确认数字结束并入栈。这是处理流式数字输入的常用技巧。

  2. 栈的实现方式 :

    这里使用了静态数组 stack[MAXN] 配合整数下标 top 来模拟栈。相比于 STL 的 std::stack,数组模拟在竞赛或高性能场景下通常更快,且能精确控制内存大小。

  3. 数据类型 :

    题目提示结果可能很大,因此栈和操作数必须使用 long long 类型,防止整数溢出。


4. 复杂度分析

  • 时间复杂度 :O(N)O(N)O(N)。其中 NNN 为字符串长度。我们只需要遍历一次字符串,每个字符的处理(入栈、出栈、计算)都是 O(1)O(1)O(1) 的操作。
  • 空间复杂度 :O(N)O(N)O(N)。最坏情况下(例如所有数字都在前面,运算符在最后),栈的大小可能接近 N/2N/2N/2。

5. 总结

本题是后缀表达式求值的模板题。掌握此题的关键在于理解**"遇数入栈,遇符计算"**的原则,并正确处理多位数的解析以及运算数的左右顺序。这种基于栈的计算模型也是许多编译器和计算器底层实现的基础。

相关推荐
晓蛋3 天前
c语言指的是什么意思
c语言·编译器·编程开发·集成开发环境·程序实例
一隅论数智3 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
傲世仙尊3 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
XiHongShi20163 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
爱吃苹果的日记本3 天前
离散数学第六课
学习·离散数学
牵猫散步的鱼儿3 天前
重载、重写(覆盖)、重定义区别
c语言
phltxy3 天前
C 语言指针:从内存地址到灵活的数据访问
c语言
phltxy3 天前
C 语言中的数据存储:从类型到二进制位
c语言
AI职业加油站3 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展