3

我已经尝试解决这个问题超过 3 个小时,但它不能 100% 工作。请帮我。

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

  • 字符串 A:house houuse househousehous
  • 字符串 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();
 }
4

5 回答 5

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 片段匹配,这很重要。

于 2013-07-31T22:19:39.767 回答
1
if(equal==size_b) cont++;

在我看来需要:

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

重置您的计数器以找到下一个匹配项。

于 2013-07-31T07:41:26.007 回答
1

您可能应该仔细阅读 scanf 手册。事实上,这适用于所有标准库函数。%[^\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)确定相等性。如果您在本练习中不能使用任何标准库函数,请编写您自己的符合标准的strlenand strncmp,并将它们手动内联到您的函数中。然后你可能会意识到你的两个最里面的循环没有做他们应该做的事情。我建议你做的这个练习是浪费时间,因为它教你做错事。如果你必须重新发明strncmpand strlen,那么通过编写你自己的strncmpand来做到这一点strlen

于 2013-07-31T07:42:28.383 回答
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;
}
于 2013-07-31T09:05:24.443 回答
-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);


    }

于 2013-07-31T21:05:46.960 回答