题目传送门

思路

  • 字符串处理
  • 注意替换词可能再次被替换从而造成错误
  • 注意删除字符之后,要控制指向字符串的指针
#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N = 1e5 + 10, M = N * 2;
const int INF = 0x3f3f3f3f3f3f3f3f;
// 判断是不是字母或者数字
bool is_word(char c)
{
    if(isdigit(c)) return 1;
    if(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
        return 1;
    return 0;
}
// 循环替换某个独立的字符串
void s_replace(string& s, string& aim, string& s_ti)
{
    int pos = 0;
    while(s.find(aim, pos) != -1)
    {
        pos = s.find(aim, pos);
        // 判断是不是独立的, 独立的才可以替换
        if((pos == 0 || !is_word(s[pos - 1]))
           && (pos + aim.size() == s.size() || !is_word(s[pos + aim.size()])))
        {
            s.replace(pos, aim.size(), s_ti);
            pos += s_ti.size();
        }
        else pos ++;
    }
}

signed main()
{
    int n;
    cin >> n;
    getchar();
    while(n --)
    {
        string s;
        getline(cin, s);
        cout << s << endl;

        // 1. 消除不合理的空格
        for(int i = 0; i < s.size(); i ++)
        {
            if(s[i] == ' ')
            {
                // 第一个空格或者最后一个空格直接删除
                if(i == 0 || i == s.size() - 1)
                {
                    s.erase(i, 1);
                    i --;
                }
                // 只有空格右边是字母或者数字的左边不是空格的时候才是合法空格
                else if(!(is_word(s[i - 1]) != ' ' && is_word(s[i + 1])))
                {
                    s.erase(i, 1);
                    i --;
                }
            }
        }

        // 2. 大写变小写 and ?->!
        for(int i = 0; i < s.size(); i ++)
        {
            if(s[i] >= 'A' && s[i] <= 'Z' && s[i] !='I')
            {
                s[i] = s[i] - 'A' + 'a';
            }
            if(s[i] == '?') s[i] = '!';
        }

        // 3. 替换独立的I和me为 you
        string aim1 = "I", aim2 = "me";
        string s_ti = "YOU";
        int pos = 0;
        s_replace(s, aim1, s_ti);
        s_replace(s, aim2, s_ti);

        // 4. 把原文中所有独立的 can you、could you 对应地换成 I can、I could
        string aim3 = "can you", aim4 = "could you";
        string s_ti3 = "I can", s_ti4 = "I could";
        s_replace(s, aim3, s_ti3);
        s_replace(s, aim4, s_ti4);

        // 最后将假的替换词(YOU)替换为为真的替换词(you)
        pos = 0;
        while(s.find(s_ti,pos) != -1)
        {
            pos = s.find(s_ti, pos);
            s.replace(pos, s_ti.size(), "you");
            pos += 3;
        }
        cout << "AI: " << s << endl;
    }
    return 0;
}