这是我对问题的简单解决方案,使用了我在评论中建议的两个循环:
#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 片段匹配,这很重要。