Count how many times each word appears in a given sentence - c

I want to count how many words occurs in a given sentence. I am using C Programming language. It can not count the last word. In a given string, It counts each word how many times occurs. If there is a sentence like red green blue blue green blue, then the program should count red 2 green 2 and blue 3. But in my case, it does not count as blue 3. rather than count blue 2 and then blue 1:
red 1
green 2
blue 2
blue
1
My code:
#include <stdio.h>
#include <string.h>
int main(void)
{
int count = 0, c = 0, i, j = 0, k, space = 0;
char str[1000], p[500][1000], str1[200], ptr1[500][1000];
char *ptr;
fgets(str, sizeof(str), stdin);
for (i = 0;i<strlen(str);i++)
{
if ((str[i] == ' ')||(str[i] == ', ')||(str[i] == '.'))
{
space++;
}
}
for (i = 0, j = 0, k = 0;j < strlen(str);j++)
{
if ((str[j] == ' ')||(str[j] == 44)||(str[j] == 46))
{
p[i][k] = '\0';
i++;
k = 0;
}
else
p[i][k++] = str[j];
}
k = 0;
for (i = 0;i <= space;i++)
{
for (j = 0;j <= space;j++)
{
if (i == j)
{
strcpy(ptr1[k], p[i]);
k++;
count++;
break;
}
else
{
if (strcmp(ptr1[j], p[i]) != 0)
continue;
else
break;
}
}
}
for (i = 0;i < count;i++)
{
for (j = 0;j <= space;j++)
{
if (strcmp(ptr1[i], p[j]) == 0)
c++;
}
printf("%s %d\n", ptr1[i], c);
c = 0;
}
return 0;
}

fgets appends line feed character (\n) to the str
Hence your str will contain
str = "red green blue blue green blue\n"
Thus blue is not matching to blue\n and counting blue\n as different word.
And same is exactly shown on your output
red 1
green 2
blue 2
blue //see 1 is printed on next line
1
Thus trim the \n as below.
size_t len = strlen(str);
if (len > 0 && str[len - 1] == '\n')
str[len - 1] = '\0';

#define MAXWORD 100
#define MAXSTRING 10000
void WordCount()
{
/*Decalaration */
char *wordArray[MAXWORD] = { 0 };
int count[MAXWORD] = {0};
char inputString[MAXSTRING];
int wordCount=0;
/*Reading data from input stream*/
fgets(inputString, sizeof(inputString), stdin);
/*Remove trailing new line char*/
inputString[strlen(inputString) -1] = 0;
/*Init string tokenizer*/
char *wordPointer = strtok(inputString, " ");
while (wordPointer)
{
int len = strlen(wordPointer);
int found = 0;
for (int i = 0; i < wordCount; i++)
{
/*check if word already processed then incrment word count*/
if (strncmp(wordArray[i], wordPointer, len)==0)
{
count[i]++;
found = 1;
break;
}
}
if (!found)
{
/*Allocate memory for string and copy for future comparision*/
wordArray[wordCount] = (char*)malloc(len + 1);
strncpy(wordArray[wordCount], wordPointer, len);
wordArray[wordCount][len] = 0;
count[wordCount]++;
wordCount++;
}
wordPointer = strtok(NULL, " ");
}
/* print words and their frequency*/
for (int i = 0; i < wordCount; i++)
{
printf("%s - %d \n", wordArray[i], count[i]);
}
}

Related

How to find the two most common letters in a string?

The purpose of my code is to tell the user what is the most common letter and the second most common letter in the string and replace them with each other, but my code doesn't work properly. It finds the most common letters but doesn't replace them or print them properly. What is the problem?
Example input:
i love this game i do do
Output (this line is printed):
Most common: i, 2nd most common: o
After that I expected this output, which is not printed:
o live thos game o di o di
Code:
int main()
{
char array[MAX_LEN] = {0};
int i = 0, j = 0;
int max = 0, secondMAX = 0, count = 0, save = 0;
char saveForNow = ' ', highest = ' ', secondHighest = ' ';
printf("Enter a string:\n");
fgets(array, MAX_LEN, stdin);
array[strcspn(array, "\n")] = 0;
for(i = 0; i < strlen(array); ++i)
{
for(j = 0; j < strlen(array); j++)
{
if(array[i] != ' ')
{
if(array[i] == array[j])
{
count++;
saveForNow = array[i];
}
}
}
if(count > max)
{
max = count;
highest = saveForNow;
}
else if((count < max) && (count > secondMAX))
{
secondMAX = count;
secondHighest = saveForNow;
}
count = 0;
}
//*I think the proplem is here
for(i = 0; i < strlen(array); i++)
{
if(array[i] == highest)
{
array[i] = secondHighest;
}
else if(array[i] == secondHighest);
{
array[i] = highest;
}
}
printf("Most common: %c, ", highest);
printf("2nd most common: %c\n", secondHighest);
printf("Swapped:\n");
printf("%s", array);
//*I think the proplem is here
}

C language - print the 3 most frequent characters from user input string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
The goal of this program is to ask user for input and print the 3 most frequent characters from user's string. After few days I managed to make this kind of work. I mean kind of because if input will be "aaaaaaabbbbbccxz" program will work just fine, but if input will be "abc" program prints wrong values. Same with "aabbc", empty string, etc. I've been trying to fix that but with no luck. I have no idea what to do.
There's my code:
#include <stdio.h>
#include <stdlib.h>
#define N 100
/*
ask user to type letter string and load it to the array.
Count apperance of ASCII characters in the string
Print 3 most frequent characters from the string and how often they appeared.
*/
int main(int argc, char *argv[])
{
int ascii[256] = {0};
char str[N];
int z, i, j, k, top, top2, top3, index, index2, index3;
printf("Type your string: \n");
scanf("%s", &str);
for(i = 0; str[i] != 0; i++)
{
++ascii[str[i]];
}
top = ascii[0];
index = 0;
for(z = 0; str[z] != 0; z++)
{
if( ascii[str[z]] > top)
{
top = ascii[str[z]];
index = z;
}
}
printf("The most frequent is %c - was %d times.\n", str[index], top);
top2 = ascii[0];
index2 = 0;
for(j = 0; str[j] != 0; j++)
{
if( ascii[str[j]] > top2 && ascii[str[j]] < top)
{
top2 = ascii[str[j]];
index2 = j;
}
}
printf("second most frequent %c %d times.\n", str[index2], top2);
top3 = ascii[0];
index3 = 0;
for(k = 0; str[k] != 0; k++)
{
if( ascii[str[k]] > top3 && ascii[str[k]] < top2 && ascii[str[k]] < top)
{
top3 = ascii[str[k]];
index3 = k;
}
}
printf("3rd most frequent %c %d times.\n", str[index3], top3);
return 0;
}
EDIT:
it works.
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(int argc, char *argv[])
{
int ascii[256] = {0};
char str[N];
int x, y, z, i, j, k, top, top2, top3, index, index2, index3, len;
do
{
printf("String input here: \n");
fgets(str, N, stdin);
//scanf("%s", &str);
}
while (str[0] == '\n');
for(i = 0; str[i] != 0; i++)
{
++ascii[str[i]];
}
top = ascii[0];
len = strlen(str);
index = -1;
for(z = 0; str[z] != 0; z++)
{
if( ascii[str[z]] > top)
{
top = ascii[str[z]];
index = z;
}
}
if (index == -1) return printf("This string is empty\n");
else if (top == 1 && len > 1) return printf("There is no repeated character in that string\n");
else if (top == len) return printf("This string contains a single character '%c' - repeated %d times\n", str[index], top);
else {
// Checks the special case where several characters are repeated n times
char characters[len+1];
int count = 0;
for(i = 0; str[i] != 0; i++)
{
if (ascii[str[i]] == top && str[i] != characters[count-1])
characters[count++] = str[i];
}
characters[count] = 0;
if (count > 1) return printf("The most frequent characters are '%s' - repeated %d times.\n", characters, top);
else printf("The most frequent character is '%c' - repeated %d times.\n", str[index], top);
}
top2 = ascii[0];
index2 = -1;
for(j = 0; str[j] != 0; j++)
{
if( ascii[str[j]] > top2 && ascii[str[j]] < top)
{
top2 = ascii[str[j]];
index2 = j;
}
}
if (index2 == -1)
{
}
else if (top2 == 1 && len > 1)
{
}
else if (top2 == len)
{
}
else {
char characters[len+1];
int count = 0;
for(y = 0; str[y] != 0; y++)
{
if (ascii[str[y]] == top2 && ascii[str[y]] < top && str[y] != characters[count-1])
characters[count++] = str[y];
}
characters[count] = 0;
if (count > 1 )
{
}
else printf("The 2nd most frequent character is '%c' - repeated %d times.\n", str[index2], top2);
}
top3 = ascii[0];
index3 = -1;
for(k = 0; str[k] != 0; k++)
{
if( ascii[str[k]] > top3 && ascii[str[k]] < top2 && ascii[str[k]] < top)
{
top3 = ascii[str[k]];
index3 = k;
}
}
if (index3 == -1)
{
}
else if (top3 == 1 && len > 1)
{
}
else if (top3 == len)
{
}
else {
char characters[len+1];
int count = 0;
for(x = 0; str[x] != 0; x++)
{
if (ascii[str[x]] == top3 && ascii[str[x]] < top && ascii[str[x]] < top2 && str[y] != characters[count-1])
characters[count++] = str[x];
}
characters[count] = 0;
if (count > 1 )
{
}
else printf("The 3rd most frequent character is '%c' - repeated %d times.\n", str[index3], top3);
}
return 0;
}
You could do something like this and handle the second and third cases using a similar logic :
len = strlen(str);
index = -1;
for(z = 0; str[z] != 0; z++)
{
if( ascii[str[z]] > top)
{
top = ascii[str[z]];
index = z;
}
}
if (index == -1) return printf("This string is empty\n");
else if (top == 1 && len > 1) return printf("There is no repeated character in that string\n");
else if (top == len) return printf("This string contains a single character '%c' - repeated %d times\n", str[index], top);
else {
// Checks the special case where several characters are repeated n times
char characters[len+1];
memset(character, 0, len+1);
int count = 0;
for(i = 0; str[i] != 0; i++)
{
if (ascii[str[i]] == top && !strchr(characters, str[i]))
characters[count++] = str[i];
}
characters[count] = 0;
if (count > 1) return printf("The most frequent characters are '%s' - repeated %d times.\n", characters, top);
else printf("The most frequent character is '%c' - repeated %d times.\n", str[index], top);
}

How many anagrams there are in a sentence in C

I was asked to write a code that returns the maximum number of anagrams (word made by transposing the letters of another word like the word “secure” is an anagram of “rescue.”).
This is what I did:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char text[1000], angrm1[1000], angrm2[1000];
int i, j, k, count = 1, flag = 0, temp, size = 0, q = 1, counter = 0, max = 0;
char**point;
printf_s("Please enter the sentence, and then press Enter:\n");
gets(text);
strcpy_s(angrm1, 1000, text);
j = 1; i = 0;
for (i = 0; i < strlen(angrm1); i = k + 2) {
for (k = i; angrm1[k + 1] != ' '&&angrm1[k + 1]!=0; k++) {
if (angrm1[i] > angrm1[i + 1]) {
temp = angrm1[k];
angrm1[k] = angrm1[k + 1];
angrm1[k + 1] = temp;
}
}
Blockquote Arrange the words
size = strlen(angrm1);
}
for (i = 0; angrm1[i] != 0; i++)
{
if (angrm1[i] == ' ')
{
angrm1[i] = 0;
count++;
}
}
point = (char*)malloc(sizeof(char)*count);
for (i = 0; i < (size - 1); i++)
{
if (angrm1[i] == 0)
{
point[q] = &point[i + 1];
q++;
}
}
for (i = 0; i < counter; i++)
{
for (q = i + 1; q < counter; q++)
{
if (point[q] == 0 || point[i] == 0)
continue;
if (!strcmp(point[q], point[i]))
{
counter++;
point[q] = 0;
}
}
if (max < counter)
max = counter;
counter = 0;
}
printf_s("The maximum (not yet) number of anagram words in this sentence is %d", &max);
}
The first part works (in my opinion).
But when I check with the debugger, it skips the loop and I get junk.
Can someone please help me by pointing to the problem, and explaining how to fix it?

Changing word in string with another word in C

I am looking for a way to change words in string.
I want to change word to another word which have more symbols than first word.
First I count the symbols of the word which i want to change with another one,
than I count how many this word is in the text which is in my program as a char array(string) and now i want to change this word with the word which has more symbols.
There is the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
Start:
printf("This program can change word or symbols combanation in text\n\n");
char text[550] = "There was a grocery shop in a town. Plenty of mice lived in that grocery shop.\nFood was in plenty for them. hey also wasted the bread\nbiscuits and fruits of the shop.\nThe grocer got really worried. So, he thought I should buy a cat\nand let it stay at the grocery. Only then I can save my things.\nHe bought a nice, big fat cat and let him stay there. The cat had a nice\nime hunting the mice and killing them.\nThe mice could not move freely now. They were afraid that\n\n";
printf("%s\n", text);
int symbols_in_text = 0;
for (int f = 0;f < 550;f++)
{
if (text[f])
{
symbols_in_text++;
}
else
{
break;
}
}
printf("Text has %i symbols\n\n", symbols_in_text);
char b[15];
printf("Which word would you like to chenge in text above?\n(Maximum quantity of Symbols is 15)\nType word or some symbol(s)\n--->>");
cin >> b;
int word_symbols=0;
for (int a = 0;a < 15;a++)
{
if (b[a])
{
word_symbols++;
}
else
{
break;
}
}
printf("Word which you have entered has %i symbols\n", word_symbols);
int word_in_text = 0;
for (int i = 0; i < 550 - word_symbols; i++)
{
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[i + j])
{
found = 0;
break;
}
}
if (found && text[i + word_symbols]==' ')
{
word_in_text++;
}
}
printf("Founded %i %s as the word an is Not the some part of the other word\n", word_in_text,b);
if (word_in_text != 0)
{
char input_word[15];
printf("Enter the word which you want to insert for first entered word\nWarning:You have to enter the world which have %i symbols\n--->>", word_symbols);
cin >> input_word;
int in_word_symbols = 0;
for (int a = 0;a < 15;a++)
{
if (input_word[a])
{
in_word_symbols++;
}
else
{
break;
}
}
printf("The word which you have entered has %i symbols\n\n", in_word_symbols);
if (word_symbols == in_word_symbols)
{
for (int i = 0; i < 550 - word_symbols; i++)
{
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[i + j])
{
found = 0;
break;
}
}
if (found != 0 && text[i + word_symbols] == ' ')
{
for (int j = 0; j < in_word_symbols; j++)
{
text[i + j] = input_word[j];
}
}
}
printf("The result is--->>\n%s\n\n//////////////////////////////////////////END OF////////////////////////////////////////\n\n", text);
}
else if (in_word_symbols > word_symbols)
{
int text_char_index = 0;
step1:
for (int count = 0; count < 550 - word_symbols; count++)
{
text_char_index++;
int found = 1;
for (int j = 0; j < word_symbols; j++)
{
if (b[j] != text[count + j])
{
found = 0;
break;
}
if (found != 0 && text[count + word_symbols] == ' ')
{
count = text_char_index-1;
goto index_changing;
insert:
for (int c = 0; c < in_word_symbols; c++)
{
text[count + c] = input_word[c];
}
if (count > 500)
{
goto printing_result;
}
else
{
continue;
}
}
}
}
index_changing:
for (int l = 466; l > text_char_index + word_symbols; --l)
{
text[l] = text[l + 1];
}
goto insert;
printing_result:
printf("The result is--->>\n%s\n\n//////////////////////////////////////////END OF////////////////////////////////////////\n\n", text);
}
}
goto Start;
return 0;
}
If I enter the word was ( - it is word which i want to change in text) and than I enter the word detected (which has more symbols than first entered word - an it is the word which i want to insert in the text in return "was")
Console output is: There detected
And I can't use in this code method or something like that, I can only use if() and for loop.
Can anyone help me to understand how to do it?
First let's get the ground rules straight -- you are not allowed to use string functions/methods in this exercise, you have to write the code out explicity using primarily if statements and loops.
Rather than create a whole separate block of code to deal with the replacement word being larger than the original, just deal with it as part of the original replacement code -- as well as deal with the possibility that the replacement word is smaller. Both require shifting the original text one way or the other based on the difference between the original word and the replacement.
Here is a rework of your code that does the above and makes a number of style changes and bug fixes. It also makes it a pure 'C' program:
#include <stdio.h>
#include <stdbool.h>
int main()
{
printf("This program can change word or character combinations in text.\n\n");
char text[1024] =
"There was a grocery shop in a town. Plenty of mice lived in that grocery shop.\n"
"Food was in plenty for them. They also wasted the bread, biscuits and fruits\n"
"of the shop. The grocer got really worried. So, he thought I should buy a cat\n"
"and let it stay at the grocery. Only then I can save my things. He bought a\n"
"nice, big fat cat and let him stay there. The cat had a nice time hunting mice\n"
"and killing them. The mice could not move freely now. They were afraid that\n";
while (true) {
printf("%s\n", text);
int characters_in_text = 0;
for (int f = 0; text[f] != '\0'; f++) // not allowed to use strlen()
{
characters_in_text++;
}
printf("Text has %i characters.\n\n", characters_in_text);
char word[17];
printf("Which word would you like to change in text above?\n");
printf("(Maximum quantity of characters is %d)\n", (int) sizeof(word) - 2);
printf("Type word or some character(s)\n");
printf("--->> ");
(void) fgets(word, sizeof(word), stdin);
int a, word_characters = 0;
for (a = 0; word[a] != '\n'; a++)
{
word_characters++;
}
word[a] = '\0';
if (word_characters == 0)
{
break; // exit program
}
printf("Word which you have entered has %i characters.\n", word_characters);
int words_in_text = 0;
for (int i = 0; i < characters_in_text - word_characters; i++)
{
bool found = true;
for (int j = 0; j < word_characters; j++)
{
if (word[j] != text[i + j])
{
found = false;
break;
}
}
if (found)
{
char next_letter = text[i + word_characters];
if (next_letter == ' ' || next_letter == '.' || next_letter == ',' || next_letter == '\n' || next_letter == '\0')
{
words_in_text++;
}
}
}
printf("Found %i instance(s) of %s that are not part of another word.\n", words_in_text, word);
char replacement_word[17];
printf("Enter the word which you want to insert for first entered word.\n");
printf("(Maximum quantity of characters is %d)\n", (int) sizeof(replacement_word) - 2);
printf("Type word or some character(s)\n");
printf("--->> ");
(void) fgets(replacement_word, sizeof(replacement_word), stdin);
int replacement_word_characters = 0;
for (a = 0; replacement_word[a] != '\n'; a++)
{
replacement_word_characters++;
}
replacement_word[a] = '\0';
printf("The word which you have entered has %i characters.\n\n", replacement_word_characters);
int text_shift = replacement_word_characters - word_characters;
for (int i = 0; i < characters_in_text - word_characters; i++)
{
bool found = true;
for (int j = 0; j < word_characters; j++)
{
if (word[j] != text[i + j])
{
found = false;
break;
}
}
if (found)
{
char next_letter = text[i + word_characters];
if (next_letter == ' ' || next_letter == '.' || next_letter == ',' || next_letter == '\n' || next_letter == '\0')
{
if (text_shift > 0)
{
for (int k = characters_in_text; k > i + word_characters - 1; k--)
{
text[k + text_shift] = text[k];
}
}
else if (text_shift < 0)
{
for (int k = i + word_characters; k < characters_in_text + 1; k++)
{
text[k + text_shift] = text[k];
}
}
characters_in_text += text_shift;
for (int j = 0; j < replacement_word_characters; j++)
{
text[i + j] = replacement_word[j];
}
}
}
}
}
return 0;
}
You can see how complicated this code gets without library functions -- testing for the possible punctuation that follows a word would be a lot easier with functions like ispunct() in ctype.h
You also computed a number of useful values in your original code but failed to use them appropriately later on in the code.
Yet to do: you've a lot of error checks to add to this code -- what if the replacement makes the text larger than the array that contains it? You check that a word isn't contained in another by testing the character after the word but fail to test the character before the work, e.g. 'other' vs. 'another'.

Sorting word occurrence in string C programming

I have been stuck on this for a while now. I wrote my program to count word occurrence in an inputted string by the user as well to sort the words alphabetically. My issue is my program runs perfectly only if there are spaces in between the words inputted. For example, if I input "to to," my program will count those two words as two different words due to the comma rather than counting it as one word in "to" as I would like it to. It is that issue for all of my delimiters in the array const char delim[]. How can I fix this issue in my program? I really appreciate any help! My code is down below:
Edit: I took Bob's suggestion to use strchr() and it worked! My only issue is my program outputs the count for delimiters now. I was thinking of possibly writing an if statement when comparing words[i] with words[j] to see if they have the same value. Is that the best approach to it?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
const char delim[] = ", . - !*()&^%$##<> ? []{}\\ / \"";
#define SIZE 1000
int main(){
char string[SIZE], words[SIZE][SIZE], temp[SIZE];
int a = 0, i = 0, j = 0, k = 0, n = 0, count;
int c = 0, cnt[26] = { 0 };
int word = 0;
int x;
printf("Enter your input string:");
fgets(string, SIZE, stdin);
string[strlen(string) - 1] = '\0';
lower(string);
/*extracting each and every string and copying to a different place */
while (string[i] != '\0'){
if (strchr(", . - !*()&^%$##<> ? []{}\\ / \"", string[i]) != NULL){
words[j][k] = '\0';
k = 0;
j++;
}else {
words[j][k++] = string[i];
}
i++;
}
words[j][k] = '\0';
n = j;
printf("Number of occurences of each word unsorted:\n");
i = 0;
/* find the frequency of each word and print the results */
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
for (a = j; a <= n; a++)
strcpy(words[a], words[a + 1]);
n--;
}
}//for
}
//word == strtok(string, delim);
/* count - indicates the frequecy of word[i] */
printf("%s\t%d\n", words[i], count);
i = i + 1;
}//while
printf("Alphabetical Order:\n");
/* sort the words in the given string */
for (i = 0; i < n; i++){
strcpy(temp, words[i]);
for (j = i + 1; j <= n; j++){
if (strcmp(words[i], words[j]) > 0){
strcpy(temp, words[j]);
strcpy(words[j], words[i]);
strcpy(words[i], temp);
}
} //inner for
} //outer for
i = 0;
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
}
}
}
printf("%s\n", words[i]);
i = i + count;
}
}
Strip every word of that delimeter before comparing. Actually you don't even need a list of delimeters because words are 'alpha' other than that it's a delimeter.
Please try this, it works, it is an extract of your own code, a little bit modified, it will give you the count, then you have to write the rest, have fun.
#include <string.h>
#define YES 1
#define NO 0
int main( )
{
char string[1000];
int i = 0;
int j = 0;
int is_this_a_word = 0;
strcpy( string, " to or not ,tobe" );
while ( string[i++] != '\0' )
{
if ( strchr( ", . - !*()&^%$##<> ? []{}\\ / \"", string[i] ) != NULL )
{
is_this_a_word = NO;
}
else
{
if ( ! is_this_a_word )
{
is_this_a_word = YES;
j++;
}
}
}
printf( "I counted %d words", j );
getchar( );
}

Resources