2012-01-18 100 views
0

我需要複製所有不在字符串中重複的單詞,並在該單詞之後放置重複單詞。如何複製給定字符串中不重複的所有單詞?

例如:

  • 輸入的文字: 「我需要重複需要」
  • 所需的輸出: 「II需要重複再重複極品」

我不能得到如何比較字符串中的單詞。這裏是我的代碼:

#include <conio.h> 
#include <string.h> 
#include <stdio.h> 
#include <ctype.h> 
#include <windows.h> 

int main() 
{ 
    system("cls"); 
      char stri[200],*sad; 
      int lenght1 = 0; 
      int i; 
    printf("Please input string\n"); 
    gets(stri); 
    sad=strtok(stri," ,.!?"); 
    while(sad!=0) 
    { 

     printf("%s\n",sad); 
     sad=strtok(NULL, " .,!?"); 
    } 
    getch(); 
    return 0; 
} 

回答

1

我的頭,第一家店在列表中的每一個字的頂部,在你得到它們的順序(這樣你就可以再次打印出來以正確的順序)。然後查看列表,檢查每個單詞的重複內容,如果發現一個單詞在兩個單詞節點上設置標誌。最後寫出列表中的單詞,如果該單詞沒有設置「多個」標誌,則寫兩次。

0

我認爲你需要兩種數據結構:一種允許快速遍歷字符串,另一種用於快速查找以查看單詞是否遇到過。

使用二叉查找樹(tutorial)進行快速查找。如果你剛剛起步,自己寫一篇文章對C來說是值得的。如果您需要更多速度,請使用trie。每個節點將存儲該字的char *和存儲該計數的size_t

建立一個鏈表來逐字地遍歷字符串。沿着輸入字符串使用strtok將它分解成單詞,就像你已經在做的那樣。在標記時,建立一個鏈接列表,其中每個節點包含一個指向其單詞開頭的指針。將每個單詞插入到二叉搜索樹中以跟蹤其計數。

完成後,回到鏈接列表的開頭。迭代每個單詞並在二叉搜索樹中查找它的計數。如果是1,則打印兩次,否則打印一次。

如果您自己編寫數據結構,應該大約有200行C語言。

0

這是我的一點點修改的功能從C++(它使用std::stringstd::vector有),所以我對於可能出現的錯誤後悔,但這裏有一個split功能使用strtok,您可以使用:

int split(char *results, int resultsDim, char* toSplit, const char *delims){ 
    char *tmpString; 
    int beginning = 0; 
    int num = 0, i=0; 
    int len = strlen(toSplit); 

    for (tmpString = strtok(toSplit, delims), i=0; 
     tmpString != NULL; tmpString = strtok(NULL, delims), ++i){ 
      strncpy((results+(num++)*resultsDim), tmpString, strlen(tmpString)); 
      (results+(num-1)*resultsDim)[i-beginning] = 0; 
      beginning = i+1; 
    }  

    if (beginning != len){ 
     strncpy((results+(num++)*resultsDim), tmpString, strlen(tmpString)); 
     (results+(num-1)*resultsDim)[len-beginning] = 0; 
    } 
    return num; 
} 

現在,你可以使用函數來獲得令牌和令牌的數量在一個單獨的字符串數組,遍歷認爲,按照一般@Joachim Pileborgs的想法,像這樣:

int main(void){ 

    int n; 
    char words[20][50+1]; 
    char flags[20] = {0}; 
    char sentence[50*20+1]; 
    int i, j; 

    printf("Get me the input: \n"); 
    fgets(stdin, sentence, 50*20); 

    n = splitString((char*)words, 50+1, sentence, " .,!?"); 

    for (i=0; i < n; ++i) 
     for (int j=0; j < n; ++j) 
      if (!strcmp(words[i], words[j])) 
       ++flags[j]; 

    for (i = 0; i < n; ++i){ 
     printf("%s ", words[i]); 
     if (flags[i] > 1) 
      printf("%s ", words[i]); 
    } 
    printf("\n"); 
} 

順便說一句,你應該注意到我用fgets代替gets函數在開頭輸入句子:這是因爲gets一般被認爲是不安全。也就是說,如果輸入的字符串是,比爲字符串保留的內存長,它將繼續將數據寫入未保留的內存。相反,fgets有一個額外的論據,說明它可以輸入的有用字符的最大數量(不包括'\0') - 因此,它肯定會停留在保留內存的邊界內。

+0

你真的應該在發佈之前測試代碼。 – Armali 2014-03-11 07:40:45

0

使用地圖散列單詞。現在更容易完成檢查重複單詞的任務。 然後,在第二遍中,您可以輸出所需的輸出。

+0

你是指'std :: map'還是建議實現一個哈希映射?這是一個'C'問題,而不是'C++',我認爲實現一個哈希映射可能比@japreiss更困難,而且效率也不高。 – penelope 2012-01-19 00:29:27

相關問題