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

C 计算一个字符串在另一个字符串中出现的次数,c,C,我已经花了3个多小时试图解决这个问题,但并没有100%奏效。请帮帮我 问题: 创建一个函数,该函数接收两个字符串(a和B),并显示字符串B的单词在a中出现的次数,而不使用任何属于库的函数。 例如: 字符串A:house house house 字符串B:house 它需要显示单词house在字符串A中显示3倍 #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <s

我已经花了3个多小时试图解决这个问题,但并没有100%奏效。请帮帮我

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

  • 字符串A:
    house house house
  • 字符串B:
    house
它需要显示单词house在字符串A中显示3倍

#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();
 }
#包括
#包括
#包括
#包括
无效计数\u字符串\u b\u a(字符*a,字符*b){
int i,j,k=0,size_a,size_b,equal=0,cont=0;
尺寸a=strlen(a);
尺寸b=strlen(b);
j=0;
对于(i=0;i
if(equal==size_b) {cont++;equal=0;}
重置计数器以查找下一个匹配项。

您可能应该这样做。事实上,这适用于所有标准库函数。
%[^\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++;
    } 
  }  
(j=0;j k=0; 相等=0;
对于(k=0;k使用
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;
}
#包括
#包括
int count_string_b_a(常量字符*a,常量字符*b){
整数计数=0;
尺寸b=标准长度(b);
常数char*p=a;
while(NULL!=(p=strstrstr(p,b))){
++计数;
p+=lenb;
}
返回计数;
}
int main(){
内部控制;
字符a[40],b[10];
printf(“A>”);
scanf(“%39[^\n]”,a);
printf(“B>”);
scanf(“%9[^\n]”,b);
cont=计数字符串a(a,b);
printf(“B\%s\”在A\%s\“\n”,B,cont,A中出现了%d次);
返回0;
}

这是我解决这个问题的方法,即计算一个单词在某个字符串中出现的次数。自定义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);


    }


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

#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;
}
#包括
静止的
int count_出现次数(常量字符*干草堆,常量字符*针)
{
整数计数=0;
for(int i=0;haystack[i]!='\0';i++)
{
int j;
对于(j=0;针[j]!='\0'&针[j]==haystack[i+j];j++)
;
如果(指针[j]='\0')
计数++;
}
返回计数;
}
内部主(空)
{
{
const char haystack[]=“豪斯豪斯豪斯豪斯”;
const char needle[]=“房子”;
printf(“草堆vs针=%d\n”,
干草堆+0,针+0,计数_出现次数(干草堆+0,针+0));
printf(“草堆vs针=%d\n”,
干草堆+1,针+1,计数出现次数(干草堆+1,针+1));
printf(“草堆vs针=%d\n”,
干草堆+1,针+0,计数_出现次数(干草堆+1,针+0));
printf(“草堆vs针=%d\n”,
干草堆+1,针+2,计数出现次数(干草堆+1,针+2));
printf(“草堆vs针=%d\n”,
干草堆+6,针+4,计数(干草堆+6,针+4));
}
{
char*haystack=“pencili pencil pencil pen penc pe pen55cil penci9 llppencil55 pencillip peplic pencillpe”;
char*needle=“铅笔”;
printf(“草堆vs针=%d\n”,
干草堆+0,针+0,计数_出现次数(干草堆+0,针+0));
}
返回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
Haystack vs pinder=3
干草堆vs针=3
干草堆vs针=2
干草堆vs针=4
干草堆vs针=3
干草堆vs针=6
存在更好的算法
上面编码的算法很幼稚;有许多更好的字符串匹配算法可用(例如,Boyer Moore、Knuth Morris Pratt:参见示例)。但是,它确实有效且易于理解。对于示例字符串,它可能并不重要;对于生物信息学和DNA片段匹配,它将非常重要。

为什么不在调试器中逐步检查代码,直到发现问题为止?“不使用任何属于库的函数”避免使用显式设计用于处理字符串的库函数的动机可能是什么?如果目标是了解这些函数如何工作,您可以研究流行实现的源代码,但可以说,能够使用它们比能够编写它们更重要。
strlen()
standard library中的函数?我必须假设允许您使用I/O函数…但可能要求不使用任何字符串搜索函数。在(k=0;的
之前的赋值
k=0
循环是多余的。不使用调试器的一个原因是算法错误。这最好通过思考而不是调试来解决。你有两个字符串,一个指针和一个草堆。对于草堆中的每个位置,你需要检查指针是否与当前位置匹配。为此,你需要两个嵌套的循环,而不是一个e、 我认为使用strstr比自己实现更容易,strstrstr是C语言的标准函数。例如A:“howhow”B:“howhow”,计数1。应该是2?注意要求“不使用任何属于库的函数”。Ob
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