2009-10-19 148 views
1

我是C編程的初學者。我試圖學習如何編寫一個拼寫檢查器來查看字典文件中的所有單詞,將它們與文章進行比較,將字典文件中不存在的所有單詞打印到控制檯上。由於我在課堂上學習malloc,因此我已經降低了每個單詞,刪除了文章中的所有標點符號,並將字符串複製到malloc中。我不知道下一步應該怎麼做,有人會給我一個提示嗎?由於檢查拼寫檢查程序C

MAIN.C

#include <stdio.h> 
#include <stdlib.h> 
char dictionary[1000000]; 
char article[100000]; 

void spellCheck(char[], char[]); 

int main(void) { 
    FILE* dict_file; 
    FILE* article_file; 
    int bytes_read; 
    char* p; 
    dict_file = fopen("american-english.txt", "r"); 
    if (dict_file == 0) { 
     printf("unable to open dictionary file \"american-english.txt\"\n"); 
     return -1; 
    } 

    article_file = fopen("article.txt", "r"); 
    if (article_file == 0) { 
     printf("unable to open file \"article.txt\"\n"); 
     return -1; 
    } 

    /* read dictionary */ 
    p = dictionary; 
    p = fgets(p, 100, dict_file); 
    while (p != 0) { 
     while (*p != '\0') { 
      p += 1; 
     } 
     p = fgets(p, 100, dict_file); 
    } 

    /* read article */ 
    p = article; 
    bytes_read = fread(p, 1, 1000, article_file); 
    p += bytes_read; 
    while (bytes_read != 0) { 
     bytes_read = fread(p, 1, 1000, article_file); 
     p += bytes_read; 
    } 
    *p = 0; 

    spellCheck(article, dictionary); 
} 

PROJECT.C

void spellCheck(char article[], char dictionary[]) { 
    int len = strlen(article) + 1; 
    int i; 
    char* tempArticle; 
    tempArticle = malloc(len); 

    if (tempArticle == NULL) { 
     printf("spellcheck: Memory allocation failed.\n"); 
     return; 
    } 

    for(i = 0; i < len; i++) 
     tempArticle[i] = tolower(article[i]); 


    i=0; 

    while (article[i] != '\0'){ 
     if (article[i] >= 33 && article[i] <= 64) 
      article[i] = ' '; 
    } 

    printf("%s", tempArticle); 

    free(tempArticle); 
} 
+2

發表了一些代碼。你用你的代碼得到了多少? – 2009-10-19 00:39:49

+0

這裏「將它們複製到malloc」是什麼意思?正如Andrew Keith指出的那樣,實際的C代碼會更容易理解。 – 2009-10-19 00:48:27

+0

剛發佈我到目前爲止 – user133466 2009-10-19 00:57:35

回答

3

如何組織數據結構將很重要。

您可能希望不僅把你的字典爲二叉樹,如Zareth提及,但做的文章一樣,這樣你就可以刪除所有重複的單詞,並讓他們有序。

當你開始通過字典搜索,如果你去過去,你的話有,那麼你可以退出開始的字母,如字典的排序這種方式。

+0

從文章中創建二叉樹所涉及的處理將遠遠超過僅僅閱讀文章和檢查每個單詞對字典的處理過程,爲什麼還需要樹形結構? – 2009-10-19 01:47:24

+0

樹結構是爲了幫助迅速擺脫重複的單詞,因爲他應該將文章分解成文字並將它們變爲動態文字某種類型的清單,爲什麼不對其進行分類,以便快速刪除重複項。 – 2009-10-19 01:51:40

+0

但刪除重複包括從頭到尾閱讀文章並根據文章詞彙的現有樹解析每個詞彙。這與從頭到尾解析文章並解析字典中的每個單詞完全相同。通過這樣做你不會節省任何時間。 – 2009-10-19 01:55:10

1

爲您的代碼下一步將是每篇文章的字比較詞典中的每一個字。使用strcmp可以很容易地進行比較,但是您存儲字典的方式會強制您使用指針來查找字典中每個新單詞的開頭。

沒有任何重大的改變,你可以做這樣的比較,但它會要求你以某種方式確定何時與字典中的所有單詞進行比較,例如通過計算字典中有多少單詞時你從文件中讀取它。

char* dictionary_word = dictionary; 
int not_found = 1; 
int i = 0; 
for (; i < dictionary_word_count; ++i) { 
    if ((not_found = strcmp(tempArticle, dictionary_word)) == 0) { 
     break; /* Word found, we're done */ 
    } 
    /* Add code to move dictionary_word to the next word here */ 
} 

當前程序的問題是將dictionary_word移動到下一個單詞中。可以通過簡單地將指針前進一個字符並檢查是否找到下一個單詞來實現。相反,我建議您創建另一個char指針數組,並讓它們指向每個單詞的開頭,並在您讀取字典文件中的單詞時指定這些指針。這將允許您在for循環的開始處執行諸如 dictionary_word = dictionary_word_pointers[i];之類的操作,以使其指向正確的單詞,而不是使用while循環來查找下一個單詞的開頭。它還具有易於分類的附加好處。

您可以事先對字典進行排序,並使用binary search加快字典查找速度,如果字典很大並且使用線性搜索搜索它太慢。

+0

以上是C++,而不是C. – 2009-10-19 01:44:48

+0

什麼是in_dictionary是做什麼的? – 2009-10-19 02:03:18

1

恭喜你,你已經加載的數據到內存中,你做的一切權利與檢查系統調用的狀態。現在,你需要用你的字典數據做更多的事情:

  1. 創建的char *指針,一個指向每個字的數組。

    char * words [100000];/*確保你有足夠的空間。 */

  2. 對於你的字典裏的每個單詞,使words的條目。有多種方法可以做到這一點,例如,使用isspacestrcspn找到其長度後,可以使用strndupdictionary複製每個單詞。

  3. 排序words(參見qsort)。
  4. 使用與步驟2中相同的方法逐字閱讀文章。
  5. 在該詞典中查找詞典(請參閱bsearch)。
  6. 將拼寫錯誤的單詞放入與words類似的另一個單詞中。

如果你想獲得幻想,你可能要考慮使用stat讓你的文件的大小和分配爲dictionary內存和article使用malloc而不是使用「幻數」或「非常大的數字」。對於工業實力C,你肯定需要這樣做。

0

'詞典'是按每行一個詞組織的嗎?你可以明智地使用'strlen()`而不是'p + = 1'的循環。據推測字典也是排序?

一旦你在內存中的字典,你不需要將整篇文章讀入內存。你可以用'fscanf()'一次讀出一個單詞,然後消除任何標點符號,所以「t'other」出現爲單詞「t」和「other」,「不」出現爲「doesn」和「t」 - 如果你喜歡。或者你可以認爲這沒有幫助。另一方面,您可能確實想刪除問號和雙引號之類的字符。

您的字典是否提供了單詞上的所有變體,或者您是否需要參與詞幹?作爲一個例子,「antidisestablishmentarianism」可以被歸結爲「反」,「dis」,「建立」,「ment」,「arian」,「ism」。

您還需要考慮將所有內容都設置爲小寫是否正確。例如,您可能會認爲「IBM」確定並且「ibm」不是;與「ICBM」和「icbm」(以及「Ibm」和「Icbm」在「正確拼寫」的任何合理定義下都是不好的)同樣如此。

你應該利用這樣的事實,即你的字典是使用二分搜索或類似的機制來排序以縮短搜索時間的。