题解:洛谷 P1597 语句解析

【题目来源】

洛谷:P1597 语句解析 - 洛谷

【题目描述】

一串长度不超过 \(255\) 的 PASCAL 语言代码,只而且只有赋值语句,赋值只能是一个一位的数字或一个变量,每条赋值语句的格式是 [变量]:=[变量或一位整数];。未赋值的变量值为 \(0\) 输出 \(a,b,c\) 的值。

【输入】

一串符合语法的 PASCAL 语言,只有 \(a,b,c\) 三个变量,而且只有赋值语句,赋值只能是一个一位的数字或一个变量,未赋值的变量值为 \(0\)

【输出】

输出 \(a,b,c\) 最终的值。

【输入样例】

a:=3;b:=4;c:=5;

【输出样例】

3 4 5

【核心思想】

  1. 问题分析:给定一串符合语法的 PASCAL 赋值语句,只包含 abc 三个变量,赋值语句格式固定为 [变量]:=[变量或一位整数];。需要按顺序执行所有赋值语句,输出最终 abc 的值。未赋值的变量初始值为 0。这是一个简单赋值语句解析与模拟问题,因为语句数量有限且格式固定,可以直接遍历字符串查找赋值模式并进行赋值。

  2. 算法选择

    • 字符串扫描 + 条件匹配:遍历字符串,当检测到 变量:= 的模式时,判断赋值源是数字(0~9)还是变量(a/b/c),然后执行相应的赋值操作。
    • 注意事项:由于语句以分号 ; 结尾,扫描时需要跳过已处理的部分,但代码中通过逐字符扫描并匹配 ii+1i+2 的方式,每处理一条语句后,i 会自动递增,但需注意避免重复匹配。
  3. 关键步骤

    • 读入:读取整个字符串 s(包含所有赋值语句)。
    • 初始化a = 0, b = 0, c = 0
    • 扫描赋值:遍历 i0s.length() - 1
      • s[i]'a's[i+1] == ':'s[i+2] == '=',则检查 s[i+3]
        • 若是数字 '0'~'9',则 a = s[i+3] - '0'
        • 若是 'b',则 a = b
        • 若是 'c',则 a = c
      • 同理处理 'b''c' 的赋值。
    • 输出:输出 abc 的值。
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n)\)\(n\) 是字符串长度(不超过 255)。
    • 空间复杂度:\(O(1)\),只使用了常数个变量。
  5. 字符串解析与模拟

    • 固定格式匹配:由于格式严格,直接通过索引定位 := 和赋值源,无需复杂的词法分析。
    • 按顺序执行:字符串中赋值语句从左到右出现,扫描顺序即为执行顺序,符合要求。
    • 变量引用:赋值源可能是变量,此时需要取该变量的当前值,因此必须按顺序执行。
    • 分号分隔:每个赋值语句以分号结束,但代码中没有显式利用分号,而是通过匹配 := 来识别,这要求 := 不会出现在别处(符合题意)。
    • 适用场景:这类“简单语言解释器”的简化版,是字符串处理与模拟的典型练习。

【算法标签】

入门 #字符串入门

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

int main()
{
    int a = 0, b = 0, c = 0;  // 定义变量:三个变量a、b、c,初始化为0
    string s;                 // 定义字符串:存储输入的赋值语句

    cin >> s;                 // 输入赋值语句字符串

    // 遍历字符串,解析赋值语句
    for (int i = 0; i < s.length(); i++)
    {
        // 检查是否为a的赋值语句(格式:a:=x)
        if (s[i] == 'a' && s[i + 1] == ':' && s[i + 2] == '=')
        {
            // 如果赋值为数字
            if (s[i + 3] >= '0' && s[i + 3] <= '9')
                a = s[i + 3] - '0';  // 将字符数字转换为整数值
            // 如果赋值为变量b
            if (s[i + 3] == 'b')
                a = b;
            // 如果赋值为变量c
            if (s[i + 3] == 'c')
                a = c;
        }

        // 检查是否为b的赋值语句(格式:b:=x)
        if (s[i] == 'b' && s[i + 1] == ':' && s[i + 2] == '=')
        {
            // 如果赋值为数字
            if (s[i + 3] >= '0' && s[i + 3] <= '9')
                b = s[i + 3] - '0';
            // 如果赋值为变量a
            if (s[i + 3] == 'a')
                b = a;
            // 如果赋值为变量c
            if (s[i + 3] == 'c')
                b = c;
        }

        // 检查是否为c的赋值语句(格式:c:=x)
        if (s[i] == 'c' && s[i + 1] == ':' && s[i + 2] == '=')
        {
            // 如果赋值为数字
            if (s[i + 3] >= '0' && s[i + 3] <= '9')
                c = s[i + 3] - '0';
            // 如果赋值为变量a
            if (s[i + 3] == 'a')
                c = a;
            // 如果赋值为变量b
            if (s[i + 3] == 'b')
                c = b;
        }
    }

    // 输出三个变量的最终值
    cout << a << " " << b << " " << c;

    return 0;  // 程序正常结束
}

【运行结果】

a:=3;b:=4;c:=5;
3 4 5
posted @ 2026-08-30 09:20  团爸讲算法  阅读(15)  评论(0)    收藏  举报