计算一个字符串出现在另一个字符串中的次数

时间:2013-07-31 07:14:25

标签: c

我已经花了3个多小时尝试解决这个问题,但它不能100%正常工作。请帮帮我。

问题: 创建一个接收两个字符串(A和B)的函数,并显示字符串B的单词出现在A中的次数,而不使用属于该库的任何函数。 例如:

  • 字符串A:house houuse househousehous
  • 字符串B:house

需要显示单词house在字符串A中出现3x。

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

void count_string_b_a(char *a, char *b){
   int i,j,k=0,size_a,size_b,equal=0,cont=0;
   size_a = strlen(a); 
   size_b = strlen(b);
   j=0;
   for(i = 0; i < size_b; i++){ 
     for(j = 0; j < size_a; j++){ 
        k=0;
        equal=0;
        for(k=0; k<size_b; k++){
           if(a[j+k] == b[i+k]) equal++;
           if(equal==size_b) cont++;
        } 
      } 
   }    
   printf("B %s appears %d times in A %s",b,cont,a);
}

int main(){
   int i;
   char a[40], b[10];
   scanf("%[^\n]s",&a); getchar();
   scanf("%[^\n]s",&b);
   count_string_b_a(a,b);
   getch();
 }

5 个答案:

答案 0 :(得分:2)

这是我对问题的简单解决方案,使用了我在评论中建议的两个循环:

#include <stdio.h>

static
int count_occurrences(const char *haystack, const char *needle)
{
    int count = 0;
    for (int i = 0; haystack[i] != '\0'; i++)
    {
        int j;
        for (j = 0; needle[j] != '\0' && needle[j] == haystack[i+j]; j++)
            ;
        if (needle[j] == '\0')
            count++;
    }
    return count;
}

int main(void)
{
    {
    const char haystack[] = "house houuse househousehous";
    const char needle[] = "house";

    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+0, needle+0, count_occurrences(haystack+0, needle+0));
    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+1, needle+1, count_occurrences(haystack+1, needle+1));
    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+1, needle+0, count_occurrences(haystack+1, needle+0));
    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+1, needle+2, count_occurrences(haystack+1, needle+2));
    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+6, needle+4, count_occurrences(haystack+6, needle+4));
    }

    {
    char *haystack = "pencil pencil penciil pen penc pe pen55cil penci9llppencil55 pencillip peplic pencilrpencilpe";
    char *needle = "pencil"; 
    printf("Haystack <<%s>> vs needle <<%s>> = %d\n",
           haystack+0, needle+0, count_occurrences(haystack+0, needle+0));
    }

    return 0;
}

请注意,出现次数的计算与出现次数的打印分开进行。报告发生次数的功能通常很有用;同时打印数据的函数不可能重复使用。通常,将I / O与计算分开是一个好主意。

示例输出:

Haystack <<house houuse househousehous>> vs needle <<house>> = 3
Haystack <<ouse houuse househousehous>> vs needle <<ouse>> = 3
Haystack <<ouse houuse househousehous>> vs needle <<house>> = 2
Haystack <<ouse houuse househousehous>> vs needle <<use>> = 4
Haystack <<houuse househousehous>> vs needle <<e>> = 3
Haystack <<pencil pencil penciil pen penc pe pen55cil penci9llppencil55 pencillip peplic pencilrpencilpe>> vs needle <<pencil>> = 6

存在更好的算法

上面编码的算法是幼稚的;有许多更好的字符串匹配算法(Boyer-Moore,Knuth-Morris-Pratt,例如:参见Exact String Matching Algorithms的例子)。然而,它确实有效且易于理解。对于示例字符串,它可能无关紧要;对于生物信息学和DNA片段匹配,它会很重要。

答案 1 :(得分:1)

if(equal==size_b) cont++;

我认为需要:

if(equal==size_b) {cont++;equal=0;}

重置你的计数器以找到下一场比赛。

答案 2 :(得分:1)

你应该read the scanf manual, carefully。实际上,这适用于所有标准库函数。 %[^\n]s不是%s格式说明符的衍生物;它是%[^\n],然后尝试读取(并丢弃)文字's'字符。我建议通过从最后删除s来修复它,并在第一次使用任何C标准库函数之前阅读手册。不要忘记检查返回值。

您允许哪些世界使用strlen,而不是strncmp?摆脱这个:

 for(j = 0; j < size_a; j++){ 
    k=0;
    equal=0;
    for(k=0; k<size_b; k++){
       if(a[j+k] == b[i+k]) equal++;
       if(equal==size_b) cont++;
    } 
  }  

使用strncmp(&a[i], b)来确定相等性。如果您在本练习中无法使用任何标准库函数,请编写自己的符合标准的strlenstrncmp,并将它们手动内联到您的函数中。然后你可能会意识到你的两个最内层循环没有按照他们应该做的那样做。我建议你做的这个练习是浪费时间,因为它教你以错误的方式做事。如果您必须重新发明strncmpstrlen,请编写自己的strncmpstrlen

答案 3 :(得分:0)

像这样使用strstr

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

int count_string_b_a(const char *a, const char *b){
    int count = 0;
    size_t lenb = strlen(b);
    const char *p = a;
    while(NULL != (p = strstr(p, b))){
        ++count;
        p += lenb;
    }
    return count;
}

int main(){
    int cont;
    char a[40], b[10];

    printf("A>");
    scanf("%39[^\n]", a);
    printf("B>");
    scanf(" %9[^\n]", b);
    cont = count_string_b_a(a, b);
    printf("B \"%s\" appears %d times in A \"%s\"\n", b, cont, a);

    return 0;
}

答案 4 :(得分:-1)

这是我在计算单词出现在某个字符串中的次数的问题。一个自定义的mystrlen()函数模仿C的strlen函数。你需要的唯一头文件是stdio.h



    #include <stdio.h>

    int mystrlen(char *s)
    {
        int length = 0;

        while(*s != '\0')
        {
            length++;
            s++;
        }
        return length;
    }

    void match(char *haystack, char* needle)
    {
            int j = 0;

            int i,counter=0;

            for(i = 0;i < mystrlen(haystack);i++)
            {

                if(haystack[i] == needle[j])
                {
                    if(j == mystrlen(needle)-1)
                    {
                        counter++;
                        j = 0;
                        continue;
                    }       
                }
                else{
                    j = 0;
                    continue;
                }
                j++;

            }
            printf("%d the counter shows",counter);
    }
    int main()
    {

        char *haystack = "house houuse househousehous";

        char *needle = "house";

        match(haystack,needle);


    }

相关问题