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!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM