PTA题目集:L1-064 估值一亿的AI核心代码 (20分)——STL(调试到吐)

本文通过一道PTA题目,详细分析了在处理字符串时常见的错误,包括行首行尾的空格处理、删除空格与转换大写字母的循环问题、使用isalnum函数替代ASCII码判断、正确使用find函数以及修改字符串顺序的重要性。通过这些经验分享,帮助读者避免在类似问题中踩坑。

原题链接
题目:
在这里插入图片描述
在这里插入图片描述

输入样例:

6
Hello ?
 Good to chat   with you
can   you speak Chinese?
Really?
Could you show me 5
What Is this prime? I,don 't know

输出样例:

Hello ?
AI: hello!
 Good to chat   with you
AI: good to chat with you
can   you speak Chinese?
AI: I can speak chinese!
Really?
AI: really!
Could you show me 5
AI: I could show you 5
What Is this prime? I,don 't know
AI: what Is this prime! you,don't know

这道题我改了一下午,总结出几个易错的地方

  1. 行首行尾可能有多个空格,不是只有一个空格
  2. 删除空格和改大写字母问号的操作不能在同一个循环里,否则会出现下标错位,erase删除后数组的长度是有变化的,因此可能导致直接跳过了大写字母和问号
  3. 建议使用isalnum函数来判断是否是字母和数字,不要用ascall码判断,不然会出现if判断语句很长很长的情况,很难找错,也很容易粗心写错
  4. 使用find函数查找字符串时要循环查找并且每次更新查找开始的下标为上一次找到的下标+1,直到找不到为止,因为find函数返回的是第一次出现目标字符串的下标
  5. (最重要的一点!!)修改can you和could you应该在修改I和me之前,因为可能出现这种情况:如果me在can或者could后面,那么就不需要改整句话,只需要将me改成you,但如果修改I,me操作在前,那么就会把修改后的me改成I can或I could,就有违背题意,相当于把can me,could me改成 I can,I could,可能说的有点绕,如果有不懂的欢迎评论区提问或者私信我。(这一点是我实在找不到bug参考了别人的代码发现的问题)

差不多解决了这些bug就能过了。

这是完整代码,如果还有不懂的详见注释

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
string m[4][2]= {"can you","* can",//*是为了防止将I can/could中的I错改为you
                "could you", "* could",
                "I","you",
                "me","you"};
int main()
{
    int n;
    cin >> n;
    getchar();
    while(n--)
    {
        string s;
        getline(cin,s);
        cout << s << endl;
        //去掉行首行末空格
        while (s[0]==' ')s.erase(s.begin());
		while (s[s.length() - 1]==' ')s.erase(s.end()-1);
		//去掉其余空格
        for(int i = 1 ; i < s.size(); i++)
        {
            if(s[i] == ' ')
            {
                //去掉连续空格
                while(s[i+1] == ' ') s.erase(i + 1 , 1);
                //去掉标点符号前的空格,isalnum是判断一个字符是否为字母或字符,在这个if里如果不是的话那一定是标点符号了
                if(!isalnum(s[i + 1])) s.erase(i,1);
            }
        }
        for(int i = 0 ; i < s.size() ; i++)
        {
            if(isupper(s[i]) && s[i] != 'I')//除I外的大写字母转小写
            {
                s[i] += 32;
            }
            else if(s[i] == '?')//问号变感叹号
            {
                s[i] = '!';
            }
        }
        for(int i = 0 ; i < 4 ; i++)
        {
            int index = s.find(m[i][0]);
            int l = m[i][0].length();
            while(index != -1)
            {
                if((index == 0 || !isalnum(s[index - 1])) && (index + l == s.size() || !isalnum(s[index + l])))
                {
                    s.replace(index,l,m[i][1]);//从index下标开始将长度为l的子串替换为m[i][1]
                }
                index = s.find(m[i][0],index + 1);//从index+1开始找,找到第一个出现目标字符串的下标
            }
        }
        cout << "AI: " << s << endl;
    }
    return 0;
}


参考代码:https://blog.csdn.net/Bob__Huang/article/details/88923743

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值