本题要求你实现一个稍微更值钱一点的 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-逻辑:顺着改用户的对话,改好就输出修改后的对话
分析后得到的全代码,得分20
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String userSpeak;
StringBuilder sb;
int start,end;
sc.nextLine();
while(n-- > 0) {
userSpeak = sc.nextLine();
System.out.println(userSpeak);
sb = new StringBuilder(userSpeak);
start=0;
end=sb.length()-1;
//删除首空格
while(start<=end && sb.charAt(start)==' ') {
sb.deleteCharAt(start);
end--;
}
//删除尾空格
while(start<=end && sb.charAt(end)==' ') {
sb.deleteCharAt(end);
end--;
}
while(start<=end) {
//转换大小写,除了I
if('A'<=sb.charAt(start) && sb.charAt(start)<='Z') {
if(sb.charAt(start)!='I') {
sb.setCharAt(start, (char)(sb.charAt(start)+32));
}
//把?转换成!
}else if(sb.charAt(start)=='?') {
sb.setCharAt(start, '!');
//删除中间空格
}else if(sb.charAt(start)==' ') {
while(start+1 <= end && sb.charAt(start+1)==' ') {
sb.deleteCharAt(start+1);
end--;
}
}
start++;
}
start = 0;
while(start<=end) {
//删除标点符号前面的空格
if(judgeTail(sb.charAt(start))) {
if(start-1>=0 && sb.charAt(start-1)==' ') {
sb.deleteCharAt(start-1);
end--;
start--;
}
//I -> you
}else if(sb.charAt(start)=='I') {
if(
(start==0 || judgeHead(sb.charAt(start-1)))
&&(start==end || judgeTail(sb.charAt(start+1)))
){
sb.setCharAt(start, 'y');
sb.insert(start+1, "ou");
end+=2;
start+=2;
}
}else if(sb.charAt(start)=='c') {
//can you -> I can
if(
(start==0 || judgeHead(sb.charAt(start-1)))
&&start+6<=end
&&sb.charAt(start+1)=='a'&&sb.charAt(start+2)=='n'
&&sb.charAt(start+3)==' '&&sb.charAt(start+4)=='y'
&&sb.charAt(start+5)=='o'&&sb.charAt(start+6)=='u'
&&(start+6==end || judgeTail(sb.charAt(start+7)))
){
sb.setCharAt(start, 'I');
sb.setCharAt(start+1, ' ');
sb.setCharAt(start+2, 'c');
sb.setCharAt(start+3, 'a');
sb.setCharAt(start+4, 'n');
sb.deleteCharAt(start+5);
sb.deleteCharAt(start+5);
end-=2;
start+=4;
//could you -> I could
}else if(
(start==0 || judgeHead(sb.charAt(start-1)))
&&start+8<=end
&&sb.charAt(start+1)=='o'&&sb.charAt(start+2)=='u'
&&sb.charAt(start+3)=='l'&&sb.charAt(start+4)=='d'
&&sb.charAt(start+5)==' '&&sb.charAt(start+6)=='y'
&&sb.charAt(start+7)=='o'&&sb.charAt(start+8)=='u'
&&(start+8==end || judgeTail(sb.charAt(start+9)))
){
sb.setCharAt(start, 'I');
sb.setCharAt(start+1, ' ');
sb.setCharAt(start+2, 'c');
sb.setCharAt(start+3, 'o');
sb.setCharAt(start+4, 'u');
sb.setCharAt(start+5, 'l');
sb.setCharAt(start+6, 'd');
sb.deleteCharAt(start+7);
sb.deleteCharAt(start+7);
end-=2;
start+=6;
}
}else if(sb.charAt(start)=='m') {
//me -> you
if(
(start==0 || judgeHead(sb.charAt(start-1)))
&&start+1<=end
&&sb.charAt(start+1)=='e'
&&(start+1==end || judgeTail(sb.charAt(start+2)))
) {
sb.setCharAt(start, 'y');
sb.setCharAt(start+1, 'o');
sb.insert(start+2, "u");
end++;
start+=3;
}
}
start++;
}
System.out.println("AI: "+sb.toString());
}
sc.close();
}
private static boolean judgeHead(char ch) {
if(ch==' ') {
return true;
}
return false;
}
private static boolean judgeTail(char ch) {
if(ch>='0'&&ch<='9')
return false;
else if(ch=='I')
return false;
else if(ch>='a'&&ch<='z')
return false;
return true;
}
}
2-逻辑:分开修改,按照题目意思一个一个完成修改
注意 题目要求4和5,,,如果分开修改
会出现:
假设用户输入 :can I
先执行要求4 :can you
再执行要求5 :I can
最后结果就变成了“I can”,但实际上正确的结果是“can you”
调换要求4和5的过程
假设用户输入 :can you
先执行要求5 :I can
再执行要求4 :you can
最后结果就变成了“you can”,但实际上正确的结果是“I can”
分析后得到的全代码,得分17,,,不知道为啥测试点3没有过?大佬帮忙看看
import java.util.Scanner;
public class Main {
private static boolean[] mark = new boolean[1001];
public static void main(String[] args) {
for(int i=0; i<1001; i++) {
mark[i] = false;
}
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String userSpeak,aiSpeak;
sc.nextLine();
while(n-- > 0) {
userSpeak = sc.nextLine();
System.out.println(userSpeak);
//转换小写,除了I 和 转换 ? 为 ! 号
aiSpeak = toLowerCase(userSpeak);
//去除空格-首 中 尾
aiSpeak = removeSpace(aiSpeak);
//can I -> can you -> I can
//把独立的 I 和 me 换成 you
aiSpeak = replaceIAndMe(aiSpeak);
//can you -> I can -> you can
//把can you 换 I can
aiSpeak = replaceCanYou(aiSpeak);
//把could you 换 I could
aiSpeak = replaceCouldYou(aiSpeak);
//删除标记
for(int i=0; i<1001; i++) {
mark[i] = false;
}
System.out.println("AI: "+aiSpeak);
}
sc.close();
}
private static String toLowerCase(String userSpeak) {
StringBuilder sb = new StringBuilder(userSpeak);
int len =sb.length();
for(int i=0;i <len; i++) {
if('A'<=sb.charAt(i) && sb.charAt(i)<='Z') {
if(sb.charAt(i) != 'I') {
sb.setCharAt(i, (char) (sb.charAt(i)+32));
}
}else if(sb.charAt(i)=='?') {
sb.setCharAt(i, '!');
}
}
return sb.toString();
}
private static String removeSpace(String aiSpeak) {
StringBuilder sb = new StringBuilder(aiSpeak);
int len = sb.length();
//首空格
while(len > 0 && sb.charAt(0)==' ') {
sb.deleteCharAt(0);
len--;
}
//尾空格
while(len>0 && sb.charAt(len-1)==' ') {
sb.deleteCharAt(len-1);
len--;
}
//中间空格
for(int i=0; i<len; i++) {
if(sb.charAt(i) == ' ') {
//删除空格后面多余的空格
while(i+1<len && sb.charAt(i+1)==' ') {
sb.deleteCharAt(i+1);
len--;
}
}
}
for(int i=0; i<len; i++) {
//删除标点符号前面的空格
if(sb.charAt(i)==' ') {
if(i+1<len && judgeTail(sb.charAt(i+1))) {
sb.deleteCharAt(i);
len--;
i--;
}
}
}
return sb.toString();
}
private static String replaceIAndMe(String aiSpeak) {
StringBuilder sb = new StringBuilder(aiSpeak);
int len =sb.length();
for(int i=0;i <len; i++) {
if(sb.charAt(i)=='I') {
if(
//I前
(i==0|| judgeHead(sb.charAt(i-1)))
&&
//I后
(i+1==len||judgeTail(sb.charAt(i+1)))
) {
mark[i] = true;
sb.setCharAt(i, 'y');
sb.insert(i+1, "ou");
len+=2;
i+=2;
}
}else if(sb.charAt(i)=='m') {
if(i+1 <len && sb.charAt(i+1)=='e') {
if(
//me前
(i==0|| judgeHead(sb.charAt(i-1)))
&&
//me后
(i+2==len||judgeTail(sb.charAt(i+2)))
) {
mark[i]=true;
sb.setCharAt(i, 'y');
sb.setCharAt(i+1, 'o');
sb.insert(i+2, "u");
len+=1;
i+=2;
}
}
}
}
return sb.toString();
}
public static String replaceCanYou(String aiSpeak) {
StringBuilder sb =new StringBuilder(aiSpeak);
int len = sb.length();
for(int i=0; i<len; i++) {
if(
(
i==0||judgeHead(sb.charAt(i-1))
)
&&i+6<len
&&sb.charAt(i)=='c'&&sb.charAt(i+1)=='a'&&sb.charAt(i+2)=='n'
&&sb.charAt(i+3)==' '&&sb.charAt(i+4)=='y'&&sb.charAt(i+5)=='o'
&&sb.charAt(i+6)=='u'&&!mark[i+4]&&
(
i+7==len || judgeTail(sb.charAt(i+7))
)
) {
sb.setCharAt(i, 'I');
sb.setCharAt(i+1, ' ');
sb.setCharAt(i+2, 'c');
sb.setCharAt(i+3, 'a');
sb.setCharAt(i+4, 'n');
sb.deleteCharAt(i+5);
sb.deleteCharAt(i+5);
len-=2;
i+=4;
}
}
return sb.toString();
}
private static String replaceCouldYou(String aiSpeak) {
StringBuilder sb =new StringBuilder(aiSpeak);
int len = sb.length();
for(int i=0; i<len; i++) {
if(
(
i==0||judgeHead(sb.charAt(i-1))
)
&&i+8<len
&&sb.charAt(i)=='c'&&sb.charAt(i+1)=='o'
&&sb.charAt(i+2)=='u'&&sb.charAt(i+3)=='l'&&sb.charAt(i+4)=='d'
&&sb.charAt(i+5)==' '&&sb.charAt(i+6)=='y'&&sb.charAt(i+7)=='o'
&&sb.charAt(i+8)=='u'&&!mark[i+6]&&
(
i+9==len || judgeTail(sb.charAt(i+9))
)
) {
sb.setCharAt(i, 'I');
sb.setCharAt(i+1, ' ');
sb.setCharAt(i+2, 'c');
sb.setCharAt(i+3, 'o');
sb.setCharAt(i+4, 'u');
sb.setCharAt(i+5, 'l');
sb.setCharAt(i+6, 'd');
sb.deleteCharAt(i+7);
sb.deleteCharAt(i+7);
len-=2;
i+=6;
}
}
return sb.toString();
}
private static boolean judgeHead(char ch) {
if(ch==' ') {
return true;
}
return false;
}
private static boolean judgeTail(char ch) {
if(ch>='0'&&ch<='9')
return false;
else if(ch=='I')
return false;
else if(ch>='a'&&ch<='z')
return false;
return true;
}
}