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

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
}

Related

Problem with counting elements in the list of names

I have made one program, where you enter a few characters (10 max). It makes you a list, count average length of surnames, tell about how much different names. But the problem is, when I enter the last number (10) - it sorts me it incorrectly (like 1, 10, 2, 3, 4, 5, 6, 7, 8, 9). Beneath I will present my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct people {
char num[2];
char surname[20];
char name[10];
} peoples[10], c;
int main()
{
int i, j, k = 0, l = 0, m = 0, n = 0;
float s = 0;
char str[100];
system("chcp 1251 > nul");
for (i = 0, j = 0; i < 10; i++, j++)
{
printf("Enter number, surname, name %d of your human: ", i + 1);
gets(str);
while (str[n] != '\n')
{
if (str[n] != ' ')
{
peoples[j].num[k] = str[n];
}
else
break;
n++;
k++;
}
n++;
k = 0;
while (str[n] != '\n')
{
if (str[n] != ' ')
{
peoples[j].surname[k] = str[n];
}
else
break;
n++;
k++;
}
n++;
k = 0;
while (str[n] != '\n')
{
if (str[n] != '\0')
{
peoples[j].name[k] = str[n];
}
else
break;
n++;
k++;
}
n = 0;
k = 0;
}
for (i = 0; i < 10; i++)
{
for (j = i + 1; j < 10; j++)
{
if (!strcmp(peoples[i].name, peoples[j].name))
m = 1;
}
if (m == 0)
l++;
m = 0;
s = s + strlen(peoples[i].surname);
}
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
if (strcmp(peoples[j].num, peoples[j+1].num) > 0)
{
c = peoples[j+1];
peoples[j+1] = peoples[j];
peoples[j] = c;
}
for (i = 0; i < 10; i++)
{
printf("%s ", peoples[i].num);
printf("%s ", peoples[i].name);
printf("%s ", peoples[i].surname);
printf("\n");
}
printf("\nYou have %d different names\n", l);
printf("Avarege lenght of surname is = %f\n", s / 10);
}
If you want to give numeric input, then use actual numeric data.
Change the num field to become an int instead of a single-character string:
struct people {
int num;
char surname[20];
char name[10];
};
Use fgets to read the line:
fgets(str, sizeof str, stdin);
[Error checking left as exercise for reader]
Then use e.g. sscanf for parse your string:
sscanf(str, "%d %s %s", &peoples[j].num, &peoples[j].name, &peoples[j].name);
[Error checking left as exercise for reader]
And finally, instead of doing your own sorting use the standard qsort function:
qsort(peoples, 10, sizeof(struct people), &compare_people_num);
With the comparison function being something like this:
int compare_people_num(const void *a, const void *b)
{
const struct people *p1 = a;
const struct people *p2 = b:
return p1->num - p2->num; // Change order to reverse sort
}
Using sscanf and qsort will make your code much simpler and easier to understand.

Last word in reverse word function

i have this reverse word function. it simply adding word to new string in reverse order . the problem with this code is it not print the last word ( first word before reverse ) . i dont know why . please help fix my code
char str[100], revstr[100];
int i, j, index, len, startIndex, endIndex;
printf("\n Please Enter any String : ");
gets(str);
len = strlen(str);
index = 0;
endIndex = len - 1;
printf("\n ***** Given String in Reverse Order ***** \n");
for(i = len - 1; i > 0; i--)
{
if(str[i] == ' ')
{
startIndex = i + 1;
for(j = startIndex; j <= endIndex; j++)
{
revstr[index] = str[j];
index++;
}
revstr[index++] = ' ';
endIndex = i - 1;
}
}
printf("\n Given String in Reverse Order = %s", revstr);
return 0;
Here's a working code:
char str[100], revstr[100];
int i, j, index, len, startIndex, endIndex;
printf("\n Please Enter any String : ");
gets(str);
len = strlen(str);
index = 0;
endIndex = len - 1;
printf("\n ***** Given String in Reverse Order ***** \n");
for(i = len - 1; i >= -1; i--)
{
if(i == -1){
startIndex = i + 1;
for(j = startIndex; j <= endIndex; j++)
{
revstr[index] = str[j];
index++;
}
revstr[index++] = ' ';
endIndex = i - 1;
break;
}
if(str[i] == ' ')
{
startIndex = i + 1;
for(j = startIndex; j <= endIndex; j++)
{
revstr[index] = str[j];
index++;
}
revstr[index++] = ' ';
endIndex = i - 1;
}
}
printf("\n Given String in Reverse Order = %s", revstr);
The problem was that you were only including a word if there was a space before it. There will be no space before the first word therefore I made the code go before the first letter and always include the first word forcefully. This code can be broken if there are more spaces than needed in the text.

Count how many times each word appears in a given sentence

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]);
}
}

C language - operation replaces mutiple array elements instead of one

I am in the process of creating hangman in C language, but there is one problem that I cannot quite grasp. When a user correctly guesses one of the letters that the word that is being guessed has, the program replaces all of previously guessed letters to the one user just put. What is the source of this problem?
#include<stdio.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int x = 0, isCompleted, matchFound, numberOfTries = 7;
char letterGuess[1];
int randomIndex = rand()%14;
const char *wordArray[14];
const char *guessedWord[10];
const char *usedLetters[17];
for (int k = 0; k < 10; k++) {
guessedWord[k] = "_";
}
wordArray[0] = "butonierka";
wordArray[1] = "centyfolia";
wordArray[2] = "chiroplast";
wordArray[3] = "cmentarzyk";
wordArray[4] = "chrustniak";
wordArray[5] = "budowniczy";
wordArray[6] = "cholewkarz";
wordArray[7] = "cornflakes";
wordArray[8] = "brzydactwo";
wordArray[9] = "germanofil";
wordArray[10] = "lichtarzyk";
wordArray[11] = "lutowniczy";
wordArray[12] = "mikrocysta";
wordArray[13] = "tryskawiec";
const char *wordToGuess = wordArray[randomIndex];
for(int i = 0; i < 10; i++) {
printf(" %s ", guessedWord[i]);
}
printf("\n");
while(numberOfTries != 0 && isCompleted != 10) {
matchFound = 0;
isCompleted = 0;
printf("Please give a lowercase letter\n");
printf("Left tries: %d\n", numberOfTries);
scanf("%s", &letterGuess);
for (int z = 0; z < 17; z++) {
if (usedLetters[z] == letterGuess[0]) {
matchFound = 1;
}
}
if (letterGuess[0] >= 'a' && letterGuess[0] <= 'z' && matchFound == 0) {
usedLetters[x] = letterGuess[0];
x++;
for (int j = 0; j < 10; j++) {
if (letterGuess[0] == wordArray[randomIndex][j])
guessedWord[j] = letterGuess;
matchFound = 1;
}
}
if (matchFound == 0) {
numberOfTries--;
}
for(int z = 0; z < 10; z++) {
printf(" %s ", guessedWord[z]);
}
printf("\n");
} else {
if (matchFound == 1) {
printf("You've already given such letter!!\n");
} else {
printf("Wrong input, please try again!\n");
}
}
for (int k = 0; k < 10; k++) {
if (guessedWord[k] != "_") {
isCompleted++;
}
}
if (isCompleted == 10) {
printf("You have correctly guessed a word! Congrats!!\n");
}
printf("\n\n");
}
printf("The word was: %s\n", wordArray[randomIndex]);
printf("Game over!!\n");
}
The problem is that you're storing letterGuess, rather than individual characters. So each time letterGuess is updated with a new guess, all references to it change. Also, letterGuess is too short, leaving no room for the terminating null character.
The best solution is to make letterGuess a char (or an int), not an array, and to make guessedWord a char [] rather than a char *[]. There is no reason to use strings for single characters. That will solve the string-sharing problem.

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?

Resources