1. 程式人生 > >拼寫檢查-一般解法-程式設計練習題

拼寫檢查-一般解法-程式設計練習題

目錄

分析:

總結:

問題:1035:拼寫檢查

檢視    提交   統計     提示        提問

總時間限制:2000ms           記憶體限制:65536kB

描述

現在有一些英語單詞需要做拼寫檢查,你的工具是一本詞典。需要檢查的單詞,有的是詞典中的單詞,有的與詞典中的單詞相似,你的任務是發現這兩種情況。單詞A與單詞B相似的情況有三種:

1、刪除單詞A的一個字母后得到單詞B;

2、用任意一個字母替換單詞A的一個字母后得到單詞B;

3、在單詞A的任意位置增加一個字母后得到單詞B。

你的任務是發現詞典中與給定單詞相同或相似的單詞。

輸入

第一部分是詞典中的單詞,從第一行開始每行一個單詞,以"#"結束。詞典中的單詞保證不重複,最多有10000個。
第二部分是需要查詢的單詞,每行一個,以"#"結束。最多有50個需要查詢的單詞。
詞典中的單詞和需要查詢的單詞均由小寫字母組成,最多包含15個字元。

輸出

按照輸入的順序,為每個需要檢查的單詞輸出一行。如果需要檢查的單詞出現在詞典中,輸出“?x is correct",?x代表需要檢查的單詞。如果需要檢查的單詞沒有出現在詞典中,則輸出"?x: ?x1 ?x2 ...?xn",其中?x代表需要檢查的單詞,?x1...?xn代表詞典中與需要檢查的單詞相似的單詞,這些單詞中間以空格隔開。如果沒有相似的單詞,輸出"?x:"即可。

樣例輸入

i
is
has
have
be
my
more
contest
me
too
if
award
#
me
aware
m
contest
hav
oo
or
i
fi
mre
#

樣例輸出

me is correct
aware: award
m: i my me
contest is correct
hav: has have
oo: too
or:
i is correct
fi: i
mre: more me

檢視         提交        統計   提示          提問

分析:

問題並不難,只要好好分析就可以做出來,不要被描述嚇住。本題只要求有一個字母不同,所以可以分為三種情況:

1、完全相同,最好使用string類,直接使用“==”遍歷字典判斷就可以,

2、長度相等,這種情況直接將不相等的字母替換為相等的字母,然後對比兩個單詞是否相等,如果相等,則代表相似,如果不等,則代表不相似。

3、長度相差1個字母,在短字串與長字串不相等的那個位置,插入多出的那個字元。然後對比兩個單詞是否相等,如果相等,則代表相似,如果不等,則代表不相似。不想等的那個字母位置可能在中間,也可能在末尾,要考慮全。

擴充套件:如果我們想要獲取和字典中單詞有至多2個字母之差的單詞,那麼該如何處理,如果還是分情況討論的話會非常複雜。這就需要使用BK樹來解決,在我們使用字典app時,有沒有發現即使輸錯幾個字母,app依然能給我們推薦想要的單詞,非常智慧。詳見:拼寫檢查程式設計題詳解-BK樹演算法

C++AC程式碼:

#include <iostream>
#include <string>
#include <vector>
#include <cmath>

using namespace std;
bool similar(string lonStr, string shorStr); //判斷單詞相似函式
int main()
{
    vector<string> dictionary;      //儲存字典單詞
    vector<string>::iterator iter;  //迭代器
    string word;                    //需要檢查的單詞
    string dic;
    bool flag = false;
    int sub =0;

    while(1)                        //讀入字典單詞
    {
        cin >> dic;
        if(dic == "#")
        {
            break;
        }
        dictionary.push_back(dic);
    }
    while(1)                            //依次判斷
    {
        cin >> word;
        if(word == "#")
        {
            break;
        }
        flag = false;
        for(iter = dictionary.begin(); iter != dictionary.end(); iter++) //判斷字典中是否存在該單詞
        {
            dic = *iter;
            if(dic == word)
            {
                cout << word << " is correct";
                flag = true;
            }
        }
        if(!flag)    //如果字典中不存在,則查詢是否有相似的單詞
        {
            cout << word << ":";
            for(iter = dictionary.begin(); iter != dictionary.end(); iter++) //遍歷字典,判斷是否相似
            {
                dic = *iter;
                sub = dic.length() - word.length();     //獲取兩個單詞長度之差,如果 <=1,則符合條件,如果>1則不可能匹配成功
                if( sub== 0)                            //兩個單詞長度相同
                {
                    for(int i=0; i< dic.length(); i++)
                    {
                        if(dic[i] != word[i])
                        {
                            string temp = word;         //注意需要新建一箇中間變數temp,不能直接修改單詞word,因為之後還會用到word
                            temp[i] = dic[i];           //將不相等的單詞替換為相等的單詞,重新比較
                            if(temp == dic)
                            {
                                cout << " "<< dic ;
                            }
                            break;
                        }
                    }
                }else if(abs(sub) == 1)                  //兩個單詞長度相差1個字母
                {
                    if(dic.length() < word.length())
                    {
                        if(similar( word , dic ))        //判斷單詞是否相似的函式similar()。
                        {
                            cout  << " "<< dic;
                        }
                    }
                    else
                    {
                        if(similar(dic,word))
                        {
                            cout << " "<< dic ;
                        }
                    }
                }
            }
        }
        cout << endl;
    }

    return 0;
}

bool similar(string lonStr, string shorStr)  //判斷單詞是否相似
{
    int lon, shor;
    lon = lonStr.length();
    shor = shorStr.length();
    string temp;
    for(int i=0; i<shor; i++)
    {
        if(lonStr[i] != shorStr[i])         //遍歷每個字母,找到不想等的字母位置
        {
            temp = shorStr.substr(0,i);
            temp = temp + lonStr[i] + shorStr.substr(i,shor-i); //在較短的單詞中插入不想等的字母,然後判斷是否相等。
            if(temp == lonStr)
            {
                return true;
            }
        }
    }
    temp = shorStr + lonStr[lon-1];     //以上判斷會漏掉最後一個字母不想等的情況,這裡補上。
    if(temp == lonStr)
    {
        return true;
    }
    else
    {
        return false;
    }
}

總結:

注意在修改時不能直接修改單詞,應該使用一箇中間變數(替身),因為原單詞我們和字典中其他單詞對比的時候還需要使用。

還有一個就是輸出格式, 

 cout << " "<< dic ;

空格要在單詞之前。