7-8 估值一亿的AI核心代码 (20分)(附详细讲解)

本文介绍了一种AI英文问答程序的设计与实现,该程序能够处理用户输入,进行文本规范化、大小写转换、特定词汇替换等操作,最终生成符合规则的回复。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题要求你实现一个稍微更值钱一点的 AI 英文问答程序,规则是:
• 无论用户说什么,首先把对方说的话在一行中原样打印出来;
• 消除原文中多余空格:把相邻单词间的多个空格换成 1 个空格,把行首尾的空格全部删掉,把标点符号前面的空格删掉;
• 把原文中所有大写英文字母变成小写,除了 I;
• 把原文中所有独立的 can you、could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词;
• 把原文中所有独立的 I 和 me 换成 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

分析

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

其中1和7为同一类问题,3和6为同一类问题,4和5为同一类问题,2为一类问题。
此题最好使用自定义函数,代码将会变得简洁明了。理论上我们应该创建四种函数(分别对应四类问题)。c语言标准库里提供丰富的函数,里面存在我们所需的函数:
1,tolower(int tolower(int c)):把字母字符转换成小写,非字母字符不做出处理.
2,isalnum(int isalnum(int c)) :判断字符变量c是否为字母或数字,若是则返回非零,否则返回零。
3,ispunct(int ispunct(int c)):检查参数c是否为标点符号或特殊符号。(checks for any printable character which is not a space or an alphanumeric character.)
5,strstr:之前的博客(7-6 敲笨钟 (10分)(附详细讲解))已讲述。
6,memset(void *memset(void *s, int c, size_t n)):某一块内存中的内容全部设置为指定的值。n为字节数。

注意:我们需要注意题目要求是将 原文中符合要求的做替换,因我们要小心替换。所以我们先将can you、could you 对应替换成 i can、i could。这样就能防止5的替换发生错误!因为使用自定义函数调用自定义函数,因此需要将最里层的函数声明写在main函数前面!此题需要掌握有关指针的基础知识!

代码展示如下:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define len 10000

void substitute(char a[][len],char* q,char* t1,char* r1,int i);
void dele(char a[][len],int i)
{
    int j=0;
    int k=0;
    int count=0;
    char temp[]="  ";
  /*把行首的空格全部删掉*/
     count=strlen(a[i]);
     for(;;)
     {
         if(a[i][0]==32)
			for(j=0;j<count;++j)
				a[i][j]=a[i][j+1];
         else
			break;
     }
     /*把相邻单词间的多个空格换成 1 个空格*/
     for(;;)
     {
         if(strstr(a[i],temp)!=NULL)
         {
            for(j=(strstr(a[i],temp)-a[i]);j<count;++j)
                a[i][j]=a[i][j+1];
         }
         else
           break;
     }
	     /*把标点符号前面的空格删掉*/
     j=0;
     for(;j<count;++j)
        if(ispunct(a[i][j+1])!=0&&a[i][j]==32)
        {
             for(k=j;k<count;++k)
                a[i][k]=a[i][k+1];
             --j;
        }
    /*把行尾的空格全部删掉*/
    for(;;)
    {
        count=strlen(a[i]);
        if(a[i][count-1]==32)
            a[i][count-1]=0;
        else
            break;
    }
    return;
}
/*把原文中所有独立的can you could you 对应地换成 I can、I could—— 这里“独立”是指被空格或标点符号分隔开的单词,把原文中所有独立的 I 和 me 换成 you*/
void replace(char a[][len],int i)
{
    char t1[]="can you";
    char t2[]="could you";
    char r1[]="i can";
    char r2[]="i could";

	char t3[]="I";
    char t4[]="me";
    char r3[]="you";
	char *q=a[i];
       
	/*can you*/    
	substitute(a,a[i],t1,r1,i);
   
    /*could you*/
	substitute(a,a[i],t2,r2,i);

	/*I*/
	substitute(a,a[i],t3,r3,i);

	/*me*/
	substitute(a,a[i],t4,r3,i);

	/* i变成I*/
	while(strstr(a[i],r1)!=NULL)
	{
		q=strstr(a[i],r1);
		*q='I';
	}
	/* i变成I*/
	while(strstr(a[i],r2)!=NULL)
	{
		q=strstr(a[i],r2);
		*q='I';
	}
    return;
}

/*把原文中所有大写英文字母变成小写,除了 I;把原文中所有的问号 ? 换成惊叹号 !;*/
void lower(char a[][len],int i)
{
    int j=0;
     /*感叹号替换*/
    for(j=0;a[i][j]!=0;++j)
      if(a[i][j]=='?')
        a[i][j]='!';
    /*变小写*/
    for(j=0;a[i][j]!=0;++j)
      if(a[i][j]!='I')
         a[i][j]=tolower(a[i][j]);
    return;
}

void substitute(char a[][len],char* q,char* t1,char* r1,int i)
{
	char temp1[len]={0};
    char temp2[len]={0};
	int count=0;
	int leap=0;
	leap=strlen(t1);
	for(;;)
    {
        if(strstr(q,t1)!=NULL)
        {
            q=strstr(q,t1);
            if((isalnum(*(q-1))!=0&&q!=a[i])||isalnum(*(q+leap))!=0)
                q=q+leap;
            else
			{
				count=q-a[i];
				strncpy(temp2,a[i],count);
				strcat(temp2,r1);
				strcpy(temp1,q+leap);
				strcat(temp2,temp1);
				strcpy(a[i],temp2);
                memset(temp1,0,len);
                memset(temp2,0,len);
			}
		}
		else
			break;
	}
	return;
}

int main(void)
{
    char a[11][len]={0};
    int i=0;
    int n=0;

    scanf("%d",&n);
    getchar();
    for(i=0;i<n;++i)
        gets(a[i]);
	for(i=0;i<n;++i)
	{
		printf("%s\n",a[i]);
		dele(a,i);
		lower(a,i);
		replace(a,i);
		printf("AI: %s\n",a[i]);
	}
    return 0;
}

总结:strstr每次只能返回第一个符合要求的位置,因此需要用指针存储此地址,因为题目要求的是把独立子字符串替换,所以我们判断strstr返回的地址是否符合我们的要求,如果不是就需要跳过查找下一个…如果符合就使用substitute函数做替换。此题处理顺序应该为删除空格、转小写、替换。因为strcat不会覆盖目的地字符串,因此我们要手动清空目的地字符串中的内容!使用memset函数即可。

<think>好的,我需要回答用户关于L1-064估值一亿AI核心代码的Java实现问题。首先,用户提到参考了四个引用,其中引用[1]、[2]、[4]都是关于Java实现的,而引用[3]是关于输出样例的。我需要综合这些信息来给出一个清晰的实现步骤和代码示例。 首先,我需要理解题目要求。根据引用[3]中的输出样例,AI需要处理用户的输入,进行一系列的文本替换和格式化。例如,将多个空格合并为一个,处理标点符号前的空格,将问号替换为感叹号,以及处理大小写和某些特定词汇的替换,如"I"改为"you"等。 接下来,我需要查看引用[1]和[4]中的Java实现方法。引用[4]提到使用BufferedReader读取输入,处理n行文本。引用[1]和[2]提到了使用正则表达式来处理文本替换,这可能涉及到多个正则表达式步骤来逐步处理不同的替换规则。 然后,我需要将这些步骤解开来。根据常见的这类题目,处理流程通常包括以下步骤: 1. 去除首尾空格,并将多个空格合并为一个。 2. 处理标点符号前的空格,确保标点前没有空格。 3. 替换问号为感叹号。 4. 处理特定词汇的大小写,如"I"改为"you","can you"改为"I can"等。 5. 调整句子的大小写,确保首字母大写,其余小写(专有名词如Chinese可能例外)。 在实现时,需要注意正则表达式的顺序,因为某些替换可能会影响后续的操作。例如,先处理空格合并,再处理标点前的空格,这样可以避免重复调整。 此外,引用[1]中的代码示例可能已经展示了如何逐步应用这些正则表达式替换。需要确保每个替换步骤正确无误,并且考虑到所有可能的边界情况,例如多个连续的标点符号或混合大小写的输入。 最后,需要测试代码是否符合引用[3]中的输出样例,确保所有的替换规则都被正确应用,特别是像“can you”替换为“I can”这样的间接替换,可能需要使用捕获组和回溯引用来处理。 总结来,实现的关键在于步骤应用正则表达式,并注意替换顺序和模式匹配的准确性。同时,处理输入输出时要注意读取多行文本,并正确格式化输出结果。</think>关于L1-064估值一亿AI核心代码的Java实现,以下是基于正则表达式处理的典型解决方案: ### 实现思路 1. **输入处理**:读取多行文本,处理前导/尾随空格 2. **文本规范化**: - 合并连续空格为单个空格 - 处理标点符号前导空格(如`Hello ?` → `Hello?`) - 替换问号为感叹号 3. **语义替换**: - 转换独立单词"I"为"you" - 转换"can you"为"I can" - 处理其他特定替换规则 4. **格式规范化**: - 首字母大写 - 专有名词保留大写(如Chinese) ### 核心代码实现 ```java import java.io.*; import java.util.regex.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); while (n-- > 0) { String input = br.readLine().trim(); String output = processAI(input); System.out.println(input + "\nAI: " + output); } } private static String processAI(String input) { // Step 1: 规范化空格和标点 String processed = input.trim() .replaceAll(" +", " ") // 合并多个空格 .replaceAll(" (\\W)", "$1") // 去除标点前空格 .replaceAll("\\?", "!") // 替换问号 .replaceAll("\\bcan you\\b", "A") // 临时标记 .replaceAll("\\bcould you\\b", "B") // 临时标记 .replaceAll("\\b(I|me)\\b", "C"); // 临时标记 // Step 2: 执行替换逻辑 processed = processed.replaceAll("A", "I can") .replaceAll("B", "I could") .replaceAll("C", "you"); // Step 3: 格式化输出 processed = processed.replaceAll("^\\w", m -> m.group().toUpperCase()) // 首字母大写 .replaceAll("(\\W)(\\w)", m -> m.group(1) + m.group(2).toLowerCase()); // 后续字母小写 return processed; } } ``` ### 关键处理步骤明 1. **空格处理**:正则表达式`replaceAll(" +", " ")`实现多个空格合并[^4] 2. **标点修正**:`replaceAll(" (\\W)", "$1")`去除标点前的冗余空格[^1] 3. **间接替换**:通过临时标记避免替换冲突(如先替换`can you`为A,最后再替换回`I can`)[^2] 4. **大小写转换**:使用正则表达式回调函数实现首字母大写和后续字母小写[^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值