I've been for more than 3 hours trying to solve this problem, but it doesn't work 100%. Please help me.
我已经花了3个多小时试图解决这个问题,但并不是100%有效。请帮助我。
Problem: Create a function that receives two strings (A and B) and show the number of times the word of string B appears in the A, without using any function that belong to the library. For example:
问题:创建一个接收两个字符串(a和B)的函数,并显示在a中出现的字符串B的次数,而不使用属于该库的任何函数。例如:
- String A:
house houuse househousehous
- 弦线A:房子和房子
- String B:
house
- 字符串B:房子
It needs to show that the word house appears 3x in string A.
它需要显示单词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 个解决方案
#1
-1
Well this is my approach at this problem of calculating how many times a word appears in a certain string. A custom mystrlen() function imitates the strlen function of C. The only header file you need is stdio.h
这是我在这个问题上的方法计算一个单词在某一字符串中出现多少次。一个定制的mystrlen()函数模仿c的strlen函数,您需要的唯一头文件是stdi .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);
}
#2
2
This is my simple-minded solution to the problem, using two loops as I suggested in a comment:
这是我对这个问题的简单解决方案,使用了我在评论中建议的两个循环:
#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;
}
Note how the calculation of the number of occurrences is done separately from the printing of the number of occurrences. The function that reports the number of occurrences could be generally useful; a function that also prints the data is unlikely to be reusable. Generally, separating I/O from computation is a good idea.
请注意,如何计算事件的数量与打印事件的数量是分开的。报告发生次数的函数通常是有用的;同样打印数据的函数不太可能是可重用的。通常,将I/O与计算分离是一个好主意。
Sample output:
样例输出:
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
Better algorithms exist
The algorithm coded above is naïve; there are many better string matching algorithms available (Boyer-Moore, Knuth-Morris-Pratt, for example: see Exact String Matching Algorithms for examples). It does, however, work and is simple to understand. For the example strings, it probably doesn't matter; for bioinformatics and DNA fragment matching, it would matter a lot.
上面编码的算法是幼稚的;有许多更好的字符串匹配算法可用(Boyer-Moore, Knuth-Morris-Pratt,例如:参见精确的字符串匹配算法示例)。然而,它确实有作用,而且很容易理解。对于示例字符串,它可能无关紧要;对于生物信息学和DNA片段的匹配,这很重要。
#3
1
if(equal==size_b) cont++;
needs in my opinion:
需要在我看来:
if(equal==size_b) {cont++;equal=0;}
to reset your counter to find a next match.
重置计数器以找到下一个匹配项。
#4
1
You should probably read the scanf manual, carefully. In fact, this goes for all standard library functions. %[^\n]s
is not a derivative of the %s
format specifier; It's a %[^\n]
followed by an attempt to read (and discard) a literal 's'
character. I suggest fixing it by removing the s
from the end, and reading the manual before using any C standard library function for the first time. Don't forget to check the return value.
您应该仔细阅读scanf手册。事实上,这适用于所有标准库函数。% ^ \[n]% s的年代不是一个导数格式说明符;这是%[^ \ n]其次是试图读(丢弃)文字' s '字符。我建议在第一次使用任何C标准库函数之前,先把末尾的s去掉,然后再阅读手册。不要忘记检查返回值。
In what world are you allowed to use strlen
, but not strncmp
? Get rid of this:
在什么情况下允许使用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++;
}
}
Use strncmp(&a[i], b)
to determine equality, instead. If you can't use any standard library functions in this exercise, then write your own standard-compliant strlen
and strncmp
, and inline them manually into your function. You might then realise that your two inner-most loops weren't doing what they were supposed to. I would suggest that this exercise you are doing is a waste of time, because it's teaching you to do things the wrong way. If you must reinvent strncmp
and strlen
, then do so by writing your own strncmp
and strlen
.
相反,使用strncmp(&a[i], b)来确定平等。如果您不能在这个练习中使用任何标准库函数,那么编写您自己的标准兼容的strlen和strncmp,并将它们手工地内联到您的函数中。你可能会意识到你的两个最里面的回路并没有做它们应该做的事情。我认为你正在做的这个练习是浪费时间,因为它教会你用错误的方式做事。如果您必须重新创建strncmp和strlen,那么可以编写自己的strncmp和strlen。
#5
0
use strstr
like this
使用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;
}
#1
-1
Well this is my approach at this problem of calculating how many times a word appears in a certain string. A custom mystrlen() function imitates the strlen function of C. The only header file you need is stdio.h
这是我在这个问题上的方法计算一个单词在某一字符串中出现多少次。一个定制的mystrlen()函数模仿c的strlen函数,您需要的唯一头文件是stdi .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);
}
#2
2
This is my simple-minded solution to the problem, using two loops as I suggested in a comment:
这是我对这个问题的简单解决方案,使用了我在评论中建议的两个循环:
#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;
}
Note how the calculation of the number of occurrences is done separately from the printing of the number of occurrences. The function that reports the number of occurrences could be generally useful; a function that also prints the data is unlikely to be reusable. Generally, separating I/O from computation is a good idea.
请注意,如何计算事件的数量与打印事件的数量是分开的。报告发生次数的函数通常是有用的;同样打印数据的函数不太可能是可重用的。通常,将I/O与计算分离是一个好主意。
Sample output:
样例输出:
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
Better algorithms exist
The algorithm coded above is naïve; there are many better string matching algorithms available (Boyer-Moore, Knuth-Morris-Pratt, for example: see Exact String Matching Algorithms for examples). It does, however, work and is simple to understand. For the example strings, it probably doesn't matter; for bioinformatics and DNA fragment matching, it would matter a lot.
上面编码的算法是幼稚的;有许多更好的字符串匹配算法可用(Boyer-Moore, Knuth-Morris-Pratt,例如:参见精确的字符串匹配算法示例)。然而,它确实有作用,而且很容易理解。对于示例字符串,它可能无关紧要;对于生物信息学和DNA片段的匹配,这很重要。
#3
1
if(equal==size_b) cont++;
needs in my opinion:
需要在我看来:
if(equal==size_b) {cont++;equal=0;}
to reset your counter to find a next match.
重置计数器以找到下一个匹配项。
#4
1
You should probably read the scanf manual, carefully. In fact, this goes for all standard library functions. %[^\n]s
is not a derivative of the %s
format specifier; It's a %[^\n]
followed by an attempt to read (and discard) a literal 's'
character. I suggest fixing it by removing the s
from the end, and reading the manual before using any C standard library function for the first time. Don't forget to check the return value.
您应该仔细阅读scanf手册。事实上,这适用于所有标准库函数。% ^ \[n]% s的年代不是一个导数格式说明符;这是%[^ \ n]其次是试图读(丢弃)文字' s '字符。我建议在第一次使用任何C标准库函数之前,先把末尾的s去掉,然后再阅读手册。不要忘记检查返回值。
In what world are you allowed to use strlen
, but not strncmp
? Get rid of this:
在什么情况下允许使用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++;
}
}
Use strncmp(&a[i], b)
to determine equality, instead. If you can't use any standard library functions in this exercise, then write your own standard-compliant strlen
and strncmp
, and inline them manually into your function. You might then realise that your two inner-most loops weren't doing what they were supposed to. I would suggest that this exercise you are doing is a waste of time, because it's teaching you to do things the wrong way. If you must reinvent strncmp
and strlen
, then do so by writing your own strncmp
and strlen
.
相反,使用strncmp(&a[i], b)来确定平等。如果您不能在这个练习中使用任何标准库函数,那么编写您自己的标准兼容的strlen和strncmp,并将它们手工地内联到您的函数中。你可能会意识到你的两个最里面的回路并没有做它们应该做的事情。我认为你正在做的这个练习是浪费时间,因为它教会你用错误的方式做事。如果您必须重新创建strncmp和strlen,那么可以编写自己的strncmp和strlen。
#5
0
use strstr
like this
使用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;
}