2011-09-30 33 views
1

我的一位朋友需要幫助統計字符串中子字符串的出現次數,並且我提出了以下代碼。有沒有人知道一個更好的方法來做到這一點?在C中計數子字符串

#include "stdio.h" 
#include "string.h" 

int main(int argc, char *argv[]) 
{ 
    char str1[50], str2[50]; 
    int i, j, l1, l2, match, count; 

    printf("String 1:\n"); 
    gets(str2); 
    printf("String 2:\n"); 
    gets(str1); 

    l1 = strlen(str1); 
    l2 = strlen(str2); 

    count = 0; 

    for(i = 0; i < l1; i++) 
    { 
     match = 0; 
     for(j = 0; j < l2; j++) 
     { 
      if(str1[i + j] == str2[j]) 
      { 
       match++; 
      } 
     } 

     if(match == l2) 
     { 
      count++; 
     } 
    } 

    printf("Substrings: %d\n", count); 
} 
+0

你爲什麼不使你的功課自己嗎? – GreenScape

+0

大聲笑它不是我的家庭作業,你可以看到我已經做到了......我只是在尋找更好的解決方案。 – guhemama

+0

使用'#include '用尖括號代替引號;這是標準說你應該做的。儘管引號有效,但它們是非常規的。 –

回答

3

不要使用或鼓勵使用gets。除了在您的代碼中引入了一個失敗點之外,它在C99中已被棄用,並將完全從C1X中消失。

正如其他人所說,strstr是你的朋友在這裏:

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
    char s1[50], s2[50]; 
    char *p; 
    size_t count = 0; 
    size_t len1; 

    printf("Gimme a string: "); 
    fflush(stdout); 
    fgets(s1, sizeof s1, stdin); 
    p = strchr(s1, '\n');   // get rid of the trailing newline 
    if (p) 
    *p = 0; 

    printf("Gimme another string: "); 
    fflush(stdout); 
    fgets(s2, sizeof s2, stdin); 
    p = strchr(s2, '\n');   // get rid of the trailing newline 
    if (p) 
    *p = 0; 

    p = s2; 
    len1 = strlen(s1); 

    while ((p = strstr(p, s1)) != NULL && p != s1) 
    { 
    count++; 
    p += len1; 
    } 

    printf("Found %lu occurrences of %s in %s\n", count, s1, s2); 
    return 0; 
} 
+1

關於不使用'gets()'的好處。儘管在C1X中它不會是標準的,但由於向後不兼容的原因,它將(可惜)在C庫中存在十年或三年。就個人而言,我認爲正確的實現是'char * gets(char * buffer){abort();返回0; }(如果編譯器知道'abort()'沒有返回,返回值是可選的)。 –

+0

感謝您的信息伴侶。 GCC總是抱怨gets(),所以我想我會嘗試熟悉fgets()嘿。只是一個簡單的問題:所有這些fflush真的需要嗎? – guhemama

+0

標準輸出(通常)是緩衝的,所以如果你寫一個沒有終止換行符的字符串,它可能不會在沒有顯式刷新的控制檯上顯示。 –

0

您可能想看看strstr函數(如果您不熟悉它)。

+0

我不認爲這個函數是在C標準中定義的。我想它只適用於非標準擴展。 – Constantinius

+0

你是對的。將我的帖子從「instr」更改爲「strstr」。謝謝。 – 0xCAFEBABE

4

這個怎麼樣:(使用strstr功能,參考here

int count = 0; 
char str1[50], str2[50]; 
char* tmp = str1; 
int count; 

printf("String 1:\n"); 
gets(str2); 
printf("String 2:\n"); 
gets(str1); 

while(*tmp != '\0' && (tmp = strstr(tmp, str2))) { 
    ++count; 
    ++tmp; 
} 
+0

它工作完美無瑕。我已經知道了strstr,但是我不知道如何使用它的返回值。簡單而高效的解決方案,謝謝! – guhemama

+0

我想你在包含_tmp = strstr(tmp,str2)_的_while_定義中缺少括號。這個答案幫了我很多,謝謝。 –

+0

@HernánErasmo:修正了它。謝謝。 – Constantinius

0
int main() 
    { 
      char *str = "This is demo"; 
      char *sub = "is"; 
      int i,j,count; 
      i=j=count=0; 
      while(str[i]!='\0') 
      { 
      if (str[i] == sub[j] && str[i+1] == sub[j+1]) 
      { 
        count++; 
      } 
      i++; 
      } 
      cout<<count; 
      return 0; 
    } 

上面的代碼工作,但這是靜態的。

0

您可以使用QString在QT庫

QString t = "yourstring"; 
t.count("yoursubstring");