P1957 口算练习题

这是一个经典的字符串处理与模拟题。这道题的核心考点在于非定长输入的处理(即如何判断当前行是给了运算符还是直接给的数字)。

解题思路

  1. 输入判断

    由于每一行的输入格式不固定(可能是 运算符 数 数,也可能是 数 数),我们不能直接用 cin >> char >> int >> int

    • 策略:每次循环先读取第一个“标记”(Token)作为字符串。
    • 检查:判断这个字符串的首字符是否为字母(a, b, c)。
      • 如果是字母:更新当前的运算符,再读取后面两个整数。
      • 如果是数字:将该字符串转换为第一个整数(使用 stoiatoi),沿用上一次的运算符,再读取第二个整数。
  2. 计算与输出

    • 根据运算符进行加减乘计算。
    • 长度获取:最简便的方法是利用 sprintf 将完整的算式(如 5+8=13)打印到一个字符数组中,然后直接获取该数组的长度(strlen)或转换为 string.length()

参考代码

#include <iostream>
#include <string>
#include <cstdio>  // 用于 sprintf
#include <cstring> // 用于 strlen
#include <cctype>  // 用于 isalpha

using namespace std;

int main() {
    int n;
    cin >> n;

    char op; // 用于记录当前的运算符
    string first_token; // 用于读取每行的第一个数据(可能是运算符,也可能是数字)

    for (int i = 0; i < n; i++) {
        cin >> first_token;

        int x, y;

        // 判断第一个数据是字母还是数字
        if (isalpha(first_token[0])) {
            op = first_token[0]; // 更新运算符
            cin >> x >> y;       // 继续读入两个数字
        } else {
            // 如果不是字母,说明是数字,转换类型
            x = stoi(first_token); // 将字符串转为整数
            cin >> y;              // 只需要再读一个数字,运算符沿用上一次的 op
        }

        int res = 0;
        char op_symbol;

        // 根据 op 执行计算
        if (op == 'a') {
            res = x + y;
            op_symbol = '+';
        } else if (op == 'b') {
            res = x - y;
            op_symbol = '-';
        } else if (op == 'c') {
            res = x * y;
            op_symbol = '*';
        }

        // 格式化输出并计算长度
        // 使用 sprintf 将结果打印到 buffer 中,方便计算总长度
        char buffer[100];
        sprintf(buffer, "%d%c%d=%d", x, op_symbol, y, res);

        cout << buffer << endl;
        cout << strlen(buffer) << endl;
    }

    return 0;
}

关键点解析

  1. isalpha() 的使用:这是判断字符是否为字母的标准库函数。对于初学者,也可以直接判断 if (first_token[0] >= 'a' && first_token[0] <= 'z')
  2. 状态保持:题目中提到“若该行为两个数据,则表示本题的运算类型与上一题相同”。这就要求我们将 op 变量定义在循环外部,或者保证在未读取新运算符时,op 的值不被清空。
  3. 算式长度计算
    • 推荐做法:如代码所示,使用 sprintf 生成完整字符串。这是处理“由数字和符号组成的混合字符串长度”最不易出错的方法。
    • 数学做法:分别计算 x, y, res 的位数,再加上符号位的数量。这种方法需要处理负数符号(例如减法结果为负数时),逻辑较繁琐,容易遗漏细节。
posted @ 2026-01-28 12:16  张一信奥  阅读(11)  评论(0)    收藏  举报