AI核心代码解题思路

输入的是字符串,故考虑使用string类的对象或者char型数组来接收输入。

首先是主函数:

int main()
{
    string s;
    int n, i;
    cin >> n;
    getchar(); //吸收回车符 
    for(i=1; i<=n; ++i){
        getline(cin, s);
        cout << s << endl;
        cout << "AI: ";
        go(s);//AI根据s输出对话    
    }
    return 0;
}
View Code

然后是go()函数的定义。

go()函数用于根据s输出对话,不要追求一步到位,我们可以预处理s,定位到s的第一个非空格字符,把s逐个复制到t中,同时处理连续空格,?,大写字母这些简单情况。

void go(string s)
{
    char t[3001];//注意输入全部是I的时候,输出长度是输入的三倍
    //string t;  

    int i, j;//i,j分别为s,t的下标
    
    //i定位到s的第一个非空字符 
    for(i=0; s[i]==' '; ++i);//循环体为空

    j = 0;     //j的初值为0
    
    //从s的第一个非空字符开始,逐个扫描,分情况复制到t
    while(s[i]!='\0'){
        if(s[i]==' ' && s[i-1]==' '){
            ++i; //如果漏了这句,有连续空格时会死循环
            continue;
        }            
        if(s[i]=='?'){
            t[j++] = '!';
            ++i;
            continue;
        }
        if(s[i]!='I'){
            t[j++] = tolower(s[i++]);
            continue;
        }
        t[j++] = s[i++]; //s[i]='I'的情况 
     }  
     
     t[j] = '\0'; //给t补上结尾符
}
View Code

不要急着往下写,我们在go()函数体最后插入一句:

cout << t << endl;
//如果t是string类的对象,则为:cout << t.data() << endl; 
View Code

本地跑一下程序,检查t是否满足这些要求:

  • 行前没有空格
  • 没有连续空格
  • 所有的?变成!
  • 没有大写字母,I除外

以上测试成功后,说明预处理成功。

接下来逐个扫描t的字符,分情况输出。

对t分情况输出,总的框架是这样的:

j = 0;
while(t[j]!='\0'){
   if(t是'I') ...... //如果是独立的'I’,...
   if(t是'm') ...... //如果是独立的me, ...
   if(t是' ') ...... //如果空格后面是标点,...
   if(t是'c') ...... //如果是独立的can you, ...

   cout << t[j++]; //以上情况都不是,所以直接输出t[j],同时j+1
}
View Code

先来试试'I':

   j = 0;
     while(t[j]!='\0'){
         if(t[j]=='I' && isSeparator(t[j-1]) && isSeparator(t[j+1])){
             cout << "you";
             ++j;
             continue;
         }
View Code

上面只处理了独立的'I'的情况。if中的t[j-1]和t[j+1]会越界吗?

如果输入的第一个字符就是'I',t[j-1]会越界;

但是t[j+1]不会越界,其边界情况是t[j+1]为'\0'。

所以上面的代码应改为:

   j = 0;
     while(t[j]!='\0'){
         if(t[j]=='I' && (j==0 || isSeparator(t[j-1])) && isSeparator(t[j+1])){
             cout << "you";
             ++j;
             continue;
         }
View Code

同理,增加处理"me"的代码:

   if(t[j]=='m' && t[j+1]=='e' && (j==0 || isSeparator(t[j-1])) && isSeparator(t[j+2])){
             cout << "you";
             j += 2;
             continue;
         }
View Code

为了检测上面转换是否正确,我们在当前while循环的最后加上输出其他情况下的t[j],同时定义isSeparator()函数:

bool isSeparator(char ch)
{//判断ch是否分隔符
//ch可能是:数字、字母、标点、空格、\0
//分隔符:!(数字、小写字母、I)
    ch = tolower(ch); 
    if(ch>='0' && ch<='9' || ch>='a' && ch<='z' || ch=='I')
        return false;
    else 
        return true;    
}
View Code

如果测试成功,继续,处理空格的情况:

if(t[j]==' ' && isPunctuation(t[j+1])){//空格的下一个是标点,不输出 
   ++j;
 }
View Code

isPunctuation()函数请自行定义。

再测试一下,如果测试成功,继续,处理can you的情况:

不告诉你哈哈哈哈哈
View Code

Congratulations!

posted @ 2019-04-11 18:55  陈晓梅  阅读(754)  评论(0编辑  收藏  举报