【PTA】L1-064 估值一亿的AI核心代码(详C++)

简介: 【PTA】L1-064 估值一亿的AI核心代码(详C++)

题目要求:

以上图片来自新浪微博。

本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;
  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
  • 把原文中所有大写英文字母变成小写,除了 I
  • 把原文中所有独立的 can youcould you 对应地换成 I canI could—— 这里“独立”是指被空格或标点符号分隔开的单词;
  • 把原文中所有独立的 Ime 换成 you
  • 把原文中所有的问号 ? 换成惊叹号 !
  • 在一行中输出替换后的句子作为 AI 的回答。

输入格式:

输入首先在第一行给出不超过 10 的正整数 N,随后 N 行,每行给出一句不超过 1000 个字符的、以回车结尾的用户的对话,对话为非空字符串,仅包括字母、数字、空格、可见的半角标点符号。

输出格式:

按题面要求输出,每个 AI 的回答前要加上 AI: 和一个空格。

输入样例:

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

代码长度限制                16 KB

时间限制                        400 ms

内存限制                        64 MB

思路:

  • 无论用户说什么,首先把对方说的话在一行中原样打印出来;(纯纯废话)
  • Hello ?
  • 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉
  •    can       you speak Chinese   ?    
  • AI: I can speak chinese!
  • 把原文中所有大写英文字母变成小写,除了 I
  •  Good to chat with you
  • AI: good to chat with you
  • 把原文中所有独立的 can youcould you 对应地换成 I canI could—— 这里“独立”是指被空格或标点符号分隔开的单词
  • What Is this prime? I,don 't know
  • AI: what Is this prime! you,don't know
  • 原文中所有独立的 Ime 换成 you
  • 原文中所有的问号 ? 换成惊叹号 !
  • can you speak Chinese?
  • AI: I can speak chinese!
  • 一行中输出替换后的句子作为 AI 的回答
  • can you speak Chinese?
  • AI: I can speak chinese!

        (1)定义了一个名为judge的函数,它接受一个字符c作为参数,并返回一个整数来标识这个字符的类型。

       (2)定义了一个名为 AI 的函数,它接受一个字符串 ask 作为输入,并返回处理后的结果。这个函数主要用于处理输入的字符串,执行一系列转换和替换操作。

头文件和命名空间:

这里包含了<bits/stdc++.h>头文件,它实际上是一个包含了C++标准库中几乎所有头文件的头文件。使用using namespace std;为了避免在代码中重复写std::前缀。

#include <bits/stdc++.h>  
 
using namespace std;

主函数:

程序的入口

int main()
 
{
 
       ....
 
}

judge的函数:

(1)判断字母

       这里首先判断c是否是大写字母('A''Z'之间)或小写字母('a''z'之间)。如果是,则返回1,并在注释中说明这是“字母”。

if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))  
    return 1;//字母

(2)判断数字

       如果c不是字母,则判断它是否是数字('0''9'之间)。如果是,则返回2,并在注释中说明这是“数字”。

else if(c>='0'&&c<='9')  
    return 2;//数字

(3)判断空格        

       如果c既不是字母也不是数字,则判断它是否是空格。如果是,则返回0,并在注释中说明这是“空格”。

else if(c==' ')  
    return 0;//空格

(4)判断标点符号

       如果c不是上述任何类型(即不是字母、数字或空格),则返回-1,并在注释中说明这是“标点符号”。

else   
    return -1;//标点符号

AI 的函数:

(1)删除行首和行尾空格

       通过两个while循环,函数删除了输入字符串ask开头的所有空格和结尾的所有空格

//删除行首空格
while(ask[0]==' ')
    ask.erase(ask.begin());
//删除行尾空格
while(ask[ask.size()-1]==' ')
    ask.erase(ask.end()-1);

(2)字符转换:

       使用for循环遍历字符串中的每个字符。

       如果字符是大写字母(除了'I'),则将其转换为小写字母。

       如果字符是问号?,则将其替换为叹号!。

       遍历过程中,如果遇到空格,则删除该空格之后的所有连续空格,只保留一个。

    for(int i=0;i<ask.size();i++)
    {
        //大写变小写
        if(ask[i]>='A'&&ask[i]<='Z'&&ask[i]!='I')
            ask[i]+=32;
        //?->!
        if(ask[i]=='?')
            ask[i]='!';
        //删除多余空格
        if(ask[i]==' ')
        {
            int j=i+1;
            while(ask[j]==' ') j++;
            ask.erase(ask.begin()+i+1,ask.begin()+j);//此处参数必须为迭代器,int不行
        }
    }

(3)字符串替换:

       再次使用for循环遍历字符串。

       如果当前字符是字符串的开头,并且为'I',则根据下一个字符的类型(通过judge函数判断)决定是否将'I'替换为'you'。

       如果当前字符和下一个字符组成的子串是"me",并且紧接着的字符不是字母或字符串结束,则同样将"me"替换为"you"。

       如果当前字符开始的子串是"can you"或"could you",并且紧接着的字符不是字母或字符串结束,则分别替换为"I can"和"I could"。

       上述替换操作在字符串的开头以及字母之前都会进行检查。

 //替换字符串
    for(int i=0;i<ask.size();i++)
    {
        if(i==0)
        {
            if(ask[i]=='I'&&(judge(ask[i+1])<=0||i+1==ask.size()))
                ask.replace(i,1,"you");
            else if(ask.substr(i,2)=="me"&&(judge(ask[i+2])<=0||i+2==ask.size()))
                ask.replace(i,2,"you");
            else if(ask.substr(i,7)=="can you"&&(judge(ask[i+7])<=0||i+7==ask.size()))
                ask.replace(i,7,"I can");
            else if(ask.substr(i,9)=="could you"&&(judge(ask[i+9])<=0||i+9==ask.size()))
                ask.replace(i,9,"I could");
        }
        if(judge(ask[i])<=0)
        {
            if(judge(ask[i+1])==1)//字母
            {
                if(ask[i+1]=='I'&&(judge(ask[i+2])<=0||i+2==ask.size()))
                    ask.replace(i+1,1,"you");
                if(ask.substr(i+1,2)=="me"&&(judge(ask[i+3])<=0||i+3==ask.size()))
                    ask.replace(i+1,2,"you");
                if(ask.substr(i+1,7)=="can you"&&(judge(ask[i+8])<=0||i+8==ask.size()))
                    ask.replace(i+1,7,"I can");
                if(ask.substr(i+1,9)=="could you"&&(judge(ask[i+10])<=0||i+10==ask.size()))
                    ask.replace(i+1,9,"I could");
            }
        }
    }

main函数:

(1)声明变量:

       int n;:用于存储用户输入的问题数量。

 string ask, ans;ask用于存储用户输入的问题,ans用于存储AI函数处理后的答案。

int n;
string ask,ans;

(2)读取问题数量

 cin >> n;:从标准输入读取用户输入的问题数量。

 cin.get();:读取并丢弃一个字符,通常是换行符,用于清除输入缓冲区中残留的换行符,避免影响后续getline的读取。

    cin>>n;
    cin.get();

(3)处理每个问题:

       while(n--):循环n次,每次循环处理一个问题。

       getline(cin, ask);:使用getline函数读取一行字符串作为问题,并存储在ask中。

       cout << ask << endl;:输出原始问题。

       ans = AI(ask);:调用AI函数处理ask,并将结果存储在ans中。

getline(cin,ask);
cout<<ask<<endl;
ans=AI(ask);

(4)输出处理后的答案:

       cout << "AI: ";:输出提示信息。

       循环遍历ans中的每个字符,并输出:

               if(ans[i]==' ' && judge(ans[i+1])<=0):判断当前字符是否是空格,并且下一个字符是否为非字母数字字符(通过judge函数判断)。如果是,则跳过该空格不输出。

               else cout << ans[i];:否则,输出当前字符。

       cout << endl;:每个问题处理完后输出换行符。

        cout<<"AI: ";
        for(int i=0;i<ans.size();i++)
        {
            //判断符号+空格+符号的特殊情况
            if(ans[i]==' '&&judge(ans[i+1])<=0)
                continue;
            else
                cout<<ans[i];
        }
        cout<<endl;

相关好用函数介绍:

字符函数:

erase函数的三种使用方法:

(1)erase(pos,n); 删除从pos开始的n个字符,比如erase(0,1)就是删除第一个字符

(2)erase(position);删除position处的一个字符(position是个string类型的迭代器)

(3)erase(first,last);删除从first到last之间的字符(first和last都是迭代器)

#include<string>
#include<iostream>
using namespace std;
int main ()
{
 
    string str ("This is an example phrase.");
 
    string::iterator it;
 
    //第(1)种方法
 
    str.erase (10,8);
 
    cout << str << endl;        // "This is an phrase."
 
    //第(2)种方法
 
    it=str.begin()+9;
 
    str.erase (it);
 
    cout << str << endl;        // "This is a phrase."
 
    //第(3)种方法
 
    str.erase (str.begin()+5, str.end()-7);
 
    cout << str << endl;        // "This phrase."
 
    return 0;
 
}

replace() 函数用法

(1)用str替换指定字符串从起始位置pos开始长度为len的字符

string& replace (size_t pos, size_t len, const string& str);

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string str = "he is@ a@ good boy";
  str=str.replace(str.find("a"),2,"#");  //从第一个a位置开始的两个字符替换成#
  cout<<str<<endl;                       //he is@ # good boy
  return 0;
}

(2) 用str替换迭代器起始位置 和 结束位置 的字符          

string& replace (const_iterator i1, const_iterator i2, const string& str);

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string str = "he is@ a@ good boy";
   str=str.replace(str.begin(),str.begin()+5,"#"); //用#替换从begin位置开始的5个字符
   cout<<str<<endl;                                //#@ a@ good boy
   return 0; 
}

(3)用substr的指定子串(给定起始位置和长度)替换从指定位置上的字符串

string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string str = "he is@ a@ good boy";
  string substr = "12345";
  str=str.replace(0,3,substr,substr.find("2"),4); //用substr的指定字符串替换str指定字符串
  cout << str << endl;                            //2345 is@ a@ good boy
  //从 str 的开始位置(即 "he")提取前3个字符,
  //并用 "2345"(从 "12345" 的第2个字符开始,提取4个字符)进行替换。
  //所以,str 的新值变为 "2345 is@ a@ good boy"。
  return 0; 
}

(4)用重复n次的c字符替换从指定位置pos长度为len的内容

string& replace (size_t pos, size_t len, size_t n, char c);

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string str = "he is@ a@ good boy";
  char  str1 = '#';
  str = str.replace(0,6,3,str1);   //用重复3次的str1字符替换的替换从位置0~6的字符串
  cout<<str<<endl;                 //### a@ good boy
  return 0; 
}

(5) 用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)内容

string& replace (const_iterator i1, const_iterator i2, size_t n, char c);

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string str = "he is@ a@ good boy";
  char  str1 = '#';
  str = str.replace(str.begin(),str.begin()+6,3,str1);   //用重复3次的str1字符替换的替换从指定迭代器位置的内容 
  cout<<str<<endl;                                       //### a@ good boy
  return 0; 
}

代码:

#include <bits/stdc++.h>
 
using namespace std;
 
 
int judge(char c)
{    //判断传入的字符是什么
    if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
        return 1;//字母
    else if(c>='0'&&c<='9')
        return 2;//数字
    else if(c==' ')
        return 0;//空格
    else 
        return -1;//标点符号
}
 
string AI(string ask)
{//返回处理结果
    //删除行首空格
    while(ask[0]==' ')
        ask.erase(ask.begin());
    //删除行尾空格
    while(ask[ask.size()-1]==' ')
        ask.erase(ask.end()-1);
    
    for(int i=0;i<ask.size();i++)
    {
        //大写变小写
        if(ask[i]>='A'&&ask[i]<='Z'&&ask[i]!='I')
            ask[i]+=32;
        //?->!
        if(ask[i]=='?')
            ask[i]='!';
        //删除多余空格
        if(ask[i]==' ')
        {
            int j=i+1;
            while(ask[j]==' ') j++;
            ask.erase(ask.begin()+i+1,ask.begin()+j);//此处参数必须为迭代器,int不行
        }
    }
    //替换字符串
    for(int i=0;i<ask.size();i++)
    {
        if(i==0)
        {
            if(ask[i]=='I'&&(judge(ask[i+1])<=0||i+1==ask.size()))
                ask.replace(i,1,"you");
            else if(ask.substr(i,2)=="me"&&(judge(ask[i+2])<=0||i+2==ask.size()))
                ask.replace(i,2,"you");
            else if(ask.substr(i,7)=="can you"&&(judge(ask[i+7])<=0||i+7==ask.size()))
                ask.replace(i,7,"I can");
            else if(ask.substr(i,9)=="could you"&&(judge(ask[i+9])<=0||i+9==ask.size()))
                ask.replace(i,9,"I could");
        }
        if(judge(ask[i])<=0)
        {
            if(judge(ask[i+1])==1)//字母
            {
                if(ask[i+1]=='I'&&(judge(ask[i+2])<=0||i+2==ask.size()))
                    ask.replace(i+1,1,"you");
                if(ask.substr(i+1,2)=="me"&&(judge(ask[i+3])<=0||i+3==ask.size()))
                    ask.replace(i+1,2,"you");
                if(ask.substr(i+1,7)=="can you"&&(judge(ask[i+8])<=0||i+8==ask.size()))
                    ask.replace(i+1,7,"I can");
                if(ask.substr(i+1,9)=="could you"&&(judge(ask[i+10])<=0||i+10==ask.size()))
                    ask.replace(i+1,9,"I could");
            }
        }
    }
 
    return ask;
}
 
int main()
{
    int n;
    string ask,ans;
    cin>>n;
    cin.get();
    while(n--)
    {
        getline(cin,ask);
        cout<<ask<<endl;
        ans=AI(ask);
        cout<<"AI: ";
        for(int i=0;i<ans.size();i++)
        {
            //判断符号+空格+符号的特殊情况
            if(ans[i]==' '&&judge(ans[i+1])<=0)
                continue;
            else
                cout<<ans[i];
        }
        cout<<endl;
    }
    return 0;
}

测试结果:

合作/推广/交流/技术学习

微信名片

目录
相关文章
|
4月前
|
人工智能 IDE Java
AI Coding实践:CodeFuse + prompt 从系分到代码
在蚂蚁国际信贷业务系统建设过程中,技术团队始终面临双重考验:一方面需应对日益加速的需求迭代周期,满足严苛的代码质量规范与金融安全合规要求;另一方面,跨地域研发团队的协同效率与代码标准统一性,在传统开发模式下逐渐显现瓶颈。为突破效率制约、提升交付质量,我们积极探索人工智能辅助代码生成技术(AI Coding)的应用实践。本文基于蚂蚁国际信贷技术团队近期的实际项目经验,梳理AI辅助开发在金融级系统快速迭代场景中的实施要点并分享阶段性实践心得。
1009 25
AI Coding实践:CodeFuse + prompt 从系分到代码
|
4月前
|
人工智能 自然语言处理 安全
氛围编程陷阱:为什么AI生成代码正在制造大量"伪开发者"
AI兴起催生“氛围编程”——用自然语言生成代码,看似高效实则陷阱。它让人跳过编程基本功,沦为只会提示、不懂原理的“中间商”。真实案例显示,此类项目易崩溃、难维护,安全漏洞频出。AI是技能倍增器,非替代品;真正强大的开发者,永远是那些基础扎实、能独立解决问题的人。
416 11
氛围编程陷阱:为什么AI生成代码正在制造大量"伪开发者"
|
4月前
|
人工智能 机器人 测试技术
AI写的代码为何金玉其外败絮其中
本文分析AI编码看着好看其实很烂的现象、原因,探索行之有效的的解决方案。并从理论上延伸到如何更好的与AI协作的方式上。
191 3
|
5月前
|
人工智能 测试技术 开发工具
如何将 AI 代码采纳率从30%提升到80%?
AI编码采纳率低的根本原因在于人类期望其独立完成模糊需求,本文提出了解决之道,讲解如何通过结构化文档和任务拆解提高AI的基础可靠性。
1389 24
|
4月前
|
人工智能 监控 Java
零代码改造 + 全链路追踪!Spring AI 最新可观测性详细解读
Spring AI Alibaba 通过集成 OpenTelemetry 实现可观测性,支持框架原生和无侵入探针两种方式。原生方案依赖 Micrometer 自动埋点,适用于快速接入;无侵入探针基于 LoongSuite 商业版,无需修改代码即可采集标准 OTLP 数据,解决了原生方案扩展性差、调用链易断链等问题。未来将开源无侵入探针方案,整合至 AgentScope Studio,并进一步增强多 Agent 场景下的观测能力。
2181 66
|
4月前
|
人工智能 安全 开发工具
C3仓库AI代码门禁通用实践:基于Qwen3-Coder+RAG的代码评审
本文介绍基于Qwen3-Coder、RAG与Iflow在C3级代码仓库落地LLM代码评审的实践,实现AI辅助人工评审。通过CI流水线自动触发,结合私域知识库与生产代码同仓管理,已成功拦截数十次高危缺陷,显著提升评审效率与质量,具备向各类代码门禁平台复用推广的价值。(239字)
944 24
|
4月前
|
数据采集 人工智能 JSON
Prompt 工程实战:如何让 AI 生成高质量的 aiohttp 异步爬虫代码
Prompt 工程实战:如何让 AI 生成高质量的 aiohttp 异步爬虫代码
|
5月前
|
设计模式 人工智能 API
AI智能体开发实战:17种核心架构模式详解与Python代码实现
本文系统解析17种智能体架构设计模式,涵盖多智能体协作、思维树、反思优化与工具调用等核心范式,结合LangChain与LangGraph实现代码工作流,并通过真实案例验证效果,助力构建高效AI系统。
714 7
|
5月前
|
存储 人工智能 数据可视化
企业级 AI 模型无代码落地指南:基于阿里云工具链,从 0 到 1 实现业务价值
某汽车零部件厂商通过阿里云PAI、OSS等工具,实现无代码AI质检落地:仅用控制台操作完成数据治理到部署,质检效率提升3倍,模型周期从2月缩至2周。本文详解全栈可视化方案,助力企业零代码落地AI。
623 1