【洛谷 | 入门5】字符串 重点题解记录

P1957 口算练习题

题目描述

王老师正在教简单算术运算。细心的王老师收集了i道学生经常做错的口算题,并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效率。王老师希望尽量减少输入的工作量,比如5+8的算式最好只要输入5和8,输出的结果要尽量详细以方便后期排版的使用,比如对于上述输入进行处理后输出 5+8=13 以及该算式的总长度6。王老师把这个光荣的任务交给你,请你帮他编程实现以上功能

输入格式

第一行为数值 i

接着的 i 行为需要输入的算式,每行可能有三个数据或两个数据

若该行为三个数据则第一个数据表示运算类型,a表示加法运算,b表示减法运算,c表示乘法运算,接着的两个数据表示参加运算的运算数

若该行为两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数

输出格式

输出2 * i 行。对于每个输入的算式,输出完整的运算式及结果,第二行输出该运算式的总长度

输入输出样例

输入#1输出#1
4
a 64 46
275 125
c 11 99
b 46 64
9

说明/提示

【数据范围】

0 < i <= 50

运算数为非负整数且小于10000

对于50%的数据,输入的算式都有三个数据,第一个算式一定有三个数据

题解

分析

因为每行可能是两个数据或者三个数据,所以获取输入时需要对每行进行判断。当该行有两个数据时,沿用保存的运算符进行运算;当该行有三个数据时,根据第一个数据更新运算符,然后在对剩下两个操作数进行运算。

思路

获取输入时,存在两种方法判断输入是哪种类型(两个数据还是三个数据):①利用cin.peek()函数观测该行的首字符是数字还是字母,从而判断类型;②根据cin的特性:当cin>>value时,会检测输入的值是否符合变量value的类型,如果不符合则指针在错误字符前停止并返回错误。尝试使用int a;cin>>a判断该行首字符是否为数字,若为数字则继续接受下一个数字的输入,若不是则调用cin.clear()清除错误标记,重新打开输入流缓存,从发生错误的位置继续接受三个数据的输入

实现

①利用cin.peek()的算法

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int n;//表示后面接受n行输入
    cin>>n;
    char opt;//运算符
    int op1, op2;//两个操作数
    string ans;//输出字符串
    //对每行输入进行处理
    for (int i = 0; i < n; i++)
    {
        //将换行符舍弃
        while (cin.peek() == '\n')
        {
            cin.get();
        }
        //观测行首字符,只观测不取出,输入指针不后移
        char c = cin.peek();
        string s;
        string len;
        //若首字符为字母,则将第一个输入数据当做运算符
        if (c == 'a' || c == 'b' || c == 'c')
        {
            cin>>opt;
        }
        //若首字符为字母,则将后两个输入数据当操作数;若首字符不为字母,则将前两个数据当做操作数
        cin>>op1>>op2;
        //根据运算符进行相应的运算,并将运算式加到输出字符串末尾
        if (opt == 'a')
        {
            s = to_string(op1) + '+' + to_string(op2) + '=' + to_string(op1+op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
        else if (opt == 'b')
        {
            s = to_string(op1) + '-' + to_string(op2) + '=' + to_string(op1-op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
        else if (opt == 'c')
        {
            s = to_string(op1) + '*' + to_string(op2) + '=' + to_string(op1*op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
    }
    cout<<ans;

    return 0;
}

②利用cin特性的算法

#include<iostream>
#include<string>
using namespace std;

int main()
{
    int n;
    cin>>n;
    char opt;
    string ans;
    for (int i = 0; i < n; i++)
    {
        int op1, op2;
        string s;
        string len;
        //判断输入是否为数字
        if(!(cin>>op1))
        {
            //若输入不为数字,则清除错误,从发生错误的输入处重新接收三个数据
            cin.clear();
            cin>>opt>>op1>>op2;
        }
        else
        {
            //若输入为数字,则接续接受下一个操作数
            cin>>op2;
        }
        if (opt == 'a')
        {
            s = to_string(op1) + '+' + to_string(op2) + '=' + to_string(op1+op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
        else if (opt == 'b')
        {
            s = to_string(op1) + '-' + to_string(op2) + '=' + to_string(op1-op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
        else if (opt == 'c')
        {
            s = to_string(op1) + '*' + to_string(op2) + '=' + to_string(op1*op2);
            len = to_string(s.length());
            ans += s + '\n' + len + '\n';
        }
    }
    cout<<ans;
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值