Counting Occurrences Of A Word In A String | C Programming Example
Vložit
- čas přidán 7. 09. 2024
- An example of counting the occurrences of a word in a string in C Source code: github.com/por.... Check out www.portfolioc... to build a portfolio that will impress employers!
Thank you. This is the exact problem we faced during our lab meeting
You’re welcome Jhune! :-)
Really like your explanations and tutorials. Just finished your C Programming course a couple of days ago and trying out these examples now. I have however, spotted a problem in this code.
You're using 'i' to iterate through the string and 'j' to iterate through the word. This approach is great as long as you do not have a word in your string which has the word that you are searching as a part.
For example,
if the string is "Notwithstanding a brilliant defence, he was found guilty and charged with a second degree offence."
If the word being searched for is "with" then the program will display the word count to be 2.
Anyways, hope you can find a solution to counter this problem in future videos :)
the way i solved it before watching the video:
int word_count(const char* str, const char* word) {
size_t str_length = strlen(str);
size_t word_length = strlen(word);
int counter = 0;
for (size_t i = 0; i < str_length; i++) {
if (*(str + i) == *(word + 0)) {
size_t j = 1;
for (j; j < word_length; j++) {
if (*(str + (i + j)) != *(word + j)) {
break;
}
}
i += j;
if (j == word_length) {
counter++;
}
}
}
return counter;
}
omg sir you saved my life !! Subscribed immediately! Much thanks!
one remark here: when a word is found we may do: j += (wlen-1);
can the word be found just one position after its 1st occurrence in the string?
let the string be "xaaaaaay" and the word be "aa".
what result would we expect? 3 or 5?
Amazing,Thanks :
// Full code
int word_count(char *string, char *word){
int slen = strlen(string);
int wlen = strlen(word);
int end = slen - wlen + 1;
int count = 0;
for(int i = 0; i < end; i++){
bool word_found = true;
for(int j = 0; j < wlen; j++){
if(word[j] != string[j+i]){
word_found = false;
break;
}
}
if(word_found){
++count;
}
}
return count;
}
Great explanation
Here's the corrected version of the sentence:
Thank you for this amazing explanation, But we want to know how we can deal with uppercase and lowercase letters and some special characters in a string. I know how to convert lower and upper characters using an ASCII code, but when it comes to special characters like ('), or even spaces as you said before, I have no idea how to work with them.
What are you trying to do with the special characters Mohammed? What is the problem you are trying to solve? Maybe I can point you in the right direction. :-)
@@PortfolioCourses I would like to handle special characters, spaces, uppercase and lowercase letters in a given string. Specifically, I am interested in identifying occurrences of the word "is," but only when it appears separately and not as part of the sentence "This is me."
The functions in the ctype library include functions that will identify when a char is uppercase, lowercase, etc, maybe that library can help you: czcams.com/video/aTSJFoqTZrI/video.html. :-)
I don't understand why you added the Asterix to the function?
Why did you make the string a pointer?
Isn't it possible to run the function without making it a pointer
We we pass a string to a function, what we are really passing is a pointer to the first char in the string. So even if we have a function like this:
void string_function(char string[]);
that is actually the exact same thing as this in practice:
void string_function(char *string);
It's the same thing with other arrays of different types too when we pass arrays to functions! :-)
This video may help: czcams.com/video/oe2bZKjiWrg/video.html. :-)
How to count the occurence of a word without typing the specific word?
When the word is "and" & string is "i understand"
The output shoud be zero
but it will print 1 because of "and" inside the word "understand" how to overcome this error
That's a great question! You would need to do some more advanced checking. It would depend on how the string could be formatted, and what assumptions if any you could make.
But you could for example only count the occurrence of the word if the character before and the character after the word is not a letter (e.g. a period, a space, etc.). So for example you could call isalpha() with the character before the word and the character after the word, and if it returns true, then you know the "word" you've found is really just part of larger word.
If the word is found right at the start of the string then you don't need to check the character before the word (because you can't), and if the word is found at the end of the string then you don't need to check the character after the word (because it's the null terminator).
Does that help and make sense? :-) Maybe I can make a video showing how to do this more advanced version too!
@@PortfolioCourses yes i would love to know how to make this check. do you have a video out yet?
@@casiebeaton7131 No, but this is still on my list of ideas to get to eventually, so thank you for sharing that you would also be interested in it too! 🙂
Same concern hopefully you do a tutorial about it soon
does the function only proceed to the nested for loop when there is a character match?
The nested for loop body will run at least once, but if the characters don't match, then it won't run again due to the break statement. :-)
hi, good tutorials that make me grow. thanks a lot. I have an issue I used this sentence: "It is is is a different word this time", to count "is", it shows count = 4. is this correct?Can you help
this has one is
one remark (or question) here:
when a word is found we may do:
if (word_found) { count++; i += (wlen-1); }
which means: a word of more than one character should not
be found just one position after its 1st character in the string.
let the string be "xaaaaaay" and the word be "aa" .
the result of counting should be: 3, not 5, right?
It depends on how you want to do it really, you could do it either way and still call it a solution to this general problem.
@@PortfolioCourses Yes, i aggree,, it means listening carefully to the task
before i watch the video i came with this solution:
int word_count(char *str, const char *word)
{
int word_len = strlen(word), count = 0, i = 0, j = 0;
while (str[i] != '\0')
{
if ( {tolower(str[i]) - tolower(word[j]) == 0)
{
j++;
if (j == word_len)
{
count++;
j = 0;
}
}
i++;
}
return count;
}
is an efficient solution or not...?
can i have feedback on this function..?
I don't think that function will produce the correct result. What if the beginning of the word is found somewhere in the string, but not the entire word? In that case j is never 'reset' to 0 by this code.
@@PortfolioCourses Thank You for time
@@__iTsMe__ You're welcome! 🙂
i thing in strtok function it will be easier but still Great explanation
I agree, I might make a video on doing it with strtok() one day too. It’s funny sometimes when students are trying to figure out how to do something they don’t want to see how it’s done with the functions that make it easier because their teachers tell them they can’t use those functions, I guess because they are trying to get them to learn more and so it the hard way. :-)
@@PortfolioCourses I'm a student of software eng. i think the result is the most important thing .. because there are many ways to solve any problem .. also in the real life work we will use the easier and low code lines.. still thank you for everything sir you are awesome .. and if it possible can you make a video how to replace a character with a word in a string
@@xturki5741 I agree, in real-world projects we do it "the easy way". 🙂 This video shows how to replace a substring with another substring: czcams.com/video/tGgl6EMZxLU/video.html. So you could have a substring of one character and replace it with a substring made up of a word, and that technique would work.
@@PortfolioCourses Thank you sir you are amazing. big love
@@xturki5741 You're very welcome! 😀
why the +1 int the
int end? is it for the '/o' ?
If the string is length 10 then we have indexes:
string[0] =
string[1] =
string[2] =
string[3] =
string[4] =
string[5] = w1
string[6] = w2
string[7] = w3
string[8] = w4
string[9] = w5
string[10] = '\0';
So then if the word is length 5, the last possible index the word could begin is index 5. Therefore, if we reach 10 - 5 + 1 = 6 then we can stop looking at that point. :-) It's just "the index where we can stop looking for the word is the index 1 beyond (+1) the last index where the word could still fit in the string".
@@PortfolioCourses thanks for the reply
Can you please do this program using StringTokenizer?
I don't think StringTokenizer is a thing that's available in C, but I could be wrong. Do you have a link to the library? Or are you asking me to make a video on using StringTokenizer in Java or C++ or another language?
@@PortfolioCourses yeah im asking you to do this in java language. java.util.StringTokenizer is there.
Ok, one day I am hoping to do Java videos but it may not be for awhile yet.
@@PortfolioCourses oh okay. Thanks.
Hello sir, I come up with the following solution. Do you think it is efficient
#include
#include
#include
int main()
{
char string[] = "world worlhdworld";
char word[] = "world";
char *sub = malloc(sizeof(word));
int count = 0;
for (int i = 0; i < strlen(string); i++)
{
if (string[i] == word[0])
{
strncpy(sub, string + i, strlen(word));
int is_equal = strcmp(sub, word);
if (is_equal == 1)
{
count++;
i += strlen(word) - 1;
}
}
}
free(sub);
return 0;
}
Great question Amine! I think it would not be too inefficient. :-) The strcmp() is not much different from just checking for a match "in-place" in the existing string. The only thing is that it's doing a strcpy() for each possible occurrence of the word based on matching the first letter, and that part could be expensive because it copies the whole word each time. Especially if it's a common first letter, like how 'e' is commonly occurring in English. The other thing is that sub has sizeof(word) but I think you need sizeof(word) + 1 for the null terminator too? Overall, this wouldn't be terribly inefficient or anything, but it's going to be more efficient to just check for the match "in place" rather than do a copy.
You're welcome. And yes, internally strcmp() does a loop, so calling strmcp() inside a loop is already like having a loop inside a loop, in terms of efficiency. :-)
--> This is my solution before watching your video
------------------
#include
#include
int is_found(char string[], char word[]){
int count=0, i;
char W[20];
for(i=0; string[i]; i+=(strlen(W)+1) ){
sscanf(string+i, "%[^' ']", W);
if( !strcmp(word, W) )
count++;
}
return count;
}
int main(void) {
char string[]= "Hi Hello Society Hi Hi Hi Hello Hello Society";
char word[10];
printf("What's the word that u search for: ");
scanf("%s", word);
printf(is_found(string, word)? "Found %d times
" : "Not found
", is_found(string, word));
return 0;
}