Hey this is my first post here. i have been assigned with an excercise to count the most frequent word in c programming language. first and foremost i need to read a number which tells me how many words i will have to read. then i need to use calloc with max element size 50. after that i read the strings. my original idea was to create a one-dimensional array which im gonna later sort alphabetically and then counting and printing the most frequent word would be easy. but after some hours of research i found out i need to use a two-dimensional array and things went out of control. ive been studying computer science for 3 months now and this exercise seems tough. do u have any other suggestions?. the example was this:
10
hello
world
goodbye
world
thanks
for
all
hello
the
fish
hello
my code so far is
int main()
{
int i, n, j, temp;
int *a;
printf("Eisagete to plhthos twn leksewn:");
scanf("%d",&n);
a = (int*)calloc(n,50);
printf("Eisagete tis %d lekseis:\n",n);
for( i=0 ; i < n ; i++ )
{
scanf("%d",&a[i]);
}
for (i = 0 ; i < ( n - 1 ); i++)
{
for (j = 0 ; j < n - i - 1; j++)
{
if (a[j] > a[j+1])
{
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
dont mind the printfs they are in greek and they are just there to make it look better. i also want to point out that this version is used for integers and not for strings just to start off.
im currently trying a linear search but im not sure if it will help
As you point out, the code you show is related to reading and sorting integers; it is only loosely related to the word counting problem.
How would you count the occurrences of each number? You'd have to
Read the next number;
If you already have a tally for the number, you add one to the tally for that number;
If you've not seen the number before, you create a tally for it and set its count to one.
When all the numbers are read, you search through the set of tallies, looking for the one with the largest count.
Record the number and count of the first entry.
For each subsequent entry:
If the count is larger than the current maximum, record the new maximum count and the entry.
Print the information about the number with the largest count and what that count is.
Replace numbers with words and the general outline will be very similar. You might allocate storage for each string (distinct word) separately.
It is easy to count the number of distinct words or the total number of words as you go. Note that you do not need to store all the words; you only need to store the distinct words. And the count at the front of the list is computer science education gone astray; you don't need the count to make it work (but you probably have to live with it being in the data; the simplest thing is to ignore the first line of input since it really doesn't help very much at all). The next simplest thing is to note that unless they're fibbing to you, the maximum number of distinct words will be the number specified, so you can pre-allocate all the space you need in one fell swoop.
Very simple. Store your words in a 2D array the loop through it and each time you take a word loop through it again starting from the current index and check if there is an equal. ech time the child loop ends check if the number of occurrences is bigger than the last maximum.
#include <stdio.h>
int main()
{
int i, j, occurrence=0, maximum = 0;
char *index_max = NULL;
char wl[10][10] = {"hello","world","goodbye","world","thanks","for","all","hello","the","world"};
for (i=0; i<10; i++){
occurrence = 0;
for (j=i; j<10; j++){
if (!strcmp(*(wl+i), *(wl+j))){
occurrence++;
}
}
if (occurrence>maximum){
maximum = occurrence;
index_max = *(wl+i);
}
}
if (index_max != NULL){
printf("The most frequent word is \"%s\" with %d occurrences.\n", index_max, maximum);
}
return 0;
}
Related
I have an assignment that basically is asking to justify a paragraph given line length. So for instance the paragraph
"I am a student of C, this is my first assignment. I hope I finish on time." given line length of 17 should be as follows:
output
I am a student of
C, this is my
first assignment.
I hope I finish
on time.
I am having trouble with dynamically placing spacing in between the words. I currently have a function that counts the words in a paragraph and stores them into a 2d array but I have no idea how to a) calculate the amount of spacing in between words and b) how to dynamically print that justified paragraph.
Here is the code I have so far:
int getAllWordsFrom2DArray(char *paragraph, char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH]) {
int i,j,totalWords = 0;
for(i=0; i < strlen(paragraph); i++) {
int wordLength;
if (paragraph[i] == ' ' || paragraph[i+1] == '\0') {
totalWords++;
wordLength = i;
for(j=0; j < wordLength; j++) {
words[i][j] = paragraph[j];
}
}
}
printf("%s", words);
return totalWords;
}
//Code in progress
int getNumberOfWordsForNextLine(int totalWords, int lineLength, char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH]) {
int wordsForNextLine = 0;
for(int i=0; i < totalWords; i++) {
wordsForNextLine = 0 ;
}
}
//code in progress
void printNextLine(int wordsForNextLine) {
}
//skeleton code provided by instructor
void justifyAndPrintParagraph(char* paragraph, int lineLength) {
char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH];
int totalWords = getAllWordsFrom2DArray(paragraph, words);
int processedWords = 0;
while (processedWords < totalWords) {
int wordsForNextLine = getNumberOfWordsForNextLine(totalWords, lineLength, words);
printNextLine(wordsForNextLine);
processedWords += wordsForNextLine;
}
}
To clarify, we are not allowed to use strlok. Essentially we are expected to just use the basics in doing this. I need to use the void justifyAndPrintParagraph function and signature but other than that I'm free to do whatever.
Edit: I forgot to add that if spaces cannot be evenly divided then the extra spaces are to be allocated left to right.
Any help is greatly appreciated.
Consider how many spaces you have to distribute. For example, given the input:
18
I am the very model of a modern Major-General.
Computing the number of words that fit on the line goes:
"I" + "am" + "the" + "very" + (4-1 words) --> 13
"I" + "am" + "the" + "very" + "model" + (5-1 words) --> 19
So only the first 4 words fit on an 18-character line. The number of space characters to distribute are then easily calculated:
N = max_line_width - sum_of_word_lengths
Now for the hard part: how many spaces between each word? Your homework expects you to divvy extra unbalanced spaces left-to-right, meaning that each pair of words may have a different number of space characters.
However, the difference will always be a single space character. Take a moment to convince yourself this is true:
I···am···the··very
-2-4-6-8-0-2-4-6-8
In our little example, we find that there are three space characters in the first two inter-word spacings, and two space characters in the last.
The minimum number of space characters per inter-word spacing is easy enough to caluclate:
nsp = N / (number_of_words_in_line - 1)
Beware! What happens if you have only one word on the line? (Do you really need to distribute spaces for such a line?)
And now, for the cool tricky math part, you can calculate the number of times you need to add a space to the inter-word spacing as:
nplus1 = N - nsp * (number_of_words_in_line - 1)
or just:
nplus1 = N % (number_of_words_in_line - 1)
Keep in mind that it is possible that all inter-word spacings are the same number of space characters, and may be exactly one space character even. Notice how our calculations work just as well in those cases.
Now you can print the words for the line in a loop, adding nsp space characters after every word, plus an extra space after the first nplus1 words.
Remember, the last word of the line doesn’t get any spaces. It is followed by a newline!
Hopefully this should help you work your way through this assignment.
(I personally think it is a bit of a careless assignment as your first ever, introduction to C class.)
And now, if I have made errors, it is because I am very, very sleepy. Someone will surely point it out if I have.
So using Dúthomhas' suggestion I was able to create the function below:
void justifyAndPrintLine(char words[MAX_NUMBER_OF_WORDS][MAX_WORD_LENGTH], int processedWords, int amountOfWordsForNextLine, int lineLength) {
int total = 0;
for (int i = processedWords; i < processedWords + amountOfWordsForNextLine; i++) {
total += (int) strlen(words[i]);
}
int spaces = lineLength - total;
int spacesBetweenWords = spaces / (amountOfWordsForNextLine - 1);
int spacesRemaining = spaces % (amountOfWordsForNextLine - 1);
int spaceForThisWord;
int leftWords = processedWords + amountOfWordsForNextLine;
while (processedWords != leftWords) {
spaceForThisWord = spacesBetweenWords;
if (spacesRemaining > 0) {
spaceForThisWord++;
spacesRemaining--;
}
printLine(words[processedWords], spaceForThisWord);
processedWords++;
}
}
A key part of my understanding of the math was that the difference in spacing was always going to a single space character. Borrowing his math I was able to properly justify the paragraph. Thanks again Dúthomhas!
I am attempting to solve this problem but I'm not sure why my solution doesn't work. My attempts at debugging tell me that the solution is attempting to access indices outside of the bounds of some of the data structures, but this does not make sense to me as it seems like my for-loop test would would.
There are probably many other issues with this solution besides this.
I'm also 90% sure that there's a more efficient way to do this. Could you help me figure out what it is I've done wrong here?
If there is a more efficient solution, what would it be? I'm struggling to deal with keeping track of the same number of spaces in the same order in an efficient way.
If any more information is necessary, please let me know and I will update.
public static void printReversed(String line){
Scanner console = new Scanner(line);
ArrayList<String> list = new ArrayList<String>(); // keeps track of words in line
int spaceOccur = 0; // keeps track of the number of times there are spaces
while (console.hasNext()){
list.add(console.next());
spaceOccur++;
}
int[] spaces = new int[spaceOccur]; // keeps track of number of spaces for each occurrence of spaces
int count = 0; // for spaces[] traversal
// searches through original input to get number of spaces
for (int i = 0; i < line.length() - 1; i++){
if (line.charAt(i) == ' '){
int j = i;
int num = 0;
// traversal through spaces to count how many
while (line.charAt(j) == (' ')){ // first error here
num++;
j++;
}
i = j; // updates for loop counter to point past spaces
spaces[count] = num; // saves number of spaces
count++;
}
}
// printing reversed input
for (int k = 0; k < list.size(); k++){
// prints reversed chars
for (int m = list.get(k).length(); m > 0; m++){
System.out.print(list.get(k).charAt(m));
}
// prints spaces
for (int n = 0; n < spaces[k]; n++){
System.out.print(" ");
}
}
}
I'd say that you're on right tracks, but some places need some closer inspection. The first loop seems to have some problems: The j++ is probably the one that goes beyond boundaries of the array - at least if you have spaces at the end of your string. And the whole loop itself seems to ignore the last character of the line.
Are you sure you even need this first loop? If I have understood correctly, the Scanner´s next() will give you strings between the spaces; in the case of two consecutive spaces I think it should return you an empty string. In this case you could just loop the list the way you do in the end of your function, and print a space character when you encounter an empty string in your list. Otherwise just print the word backwards, just like you already do (except that it should be m-- instead of m++ in the last for loop).
But if the Scanner won't give you the empty strings when there are two or more consecutive space characters, I bet the string's split() method should work.
I have a problem that I can not figure out (it is probably an easy solution but I can not see it).
The thing is, I have a program that generates all the possible combinations of numbers. The program ask for the size of the set and size of the subsets and generates all the possible combinations accordingly. So far so good ... now ...
I want to write some routines that check for some things in order to eliminate those combinations, one of those routines is the one who checks the array looking to exclude the sequences that exceed a given number of sequenced numbers, for this the program asks for the maximum of numbers in sequences allowed. For example
Size of the set ? : 10 (stores in n)
size of the subset?: 10 (stores in k)
maximum of seq num: 10 (stores in maxp)
the array is called comb[] (integer) it is initialized as
for (i = 0; i < k; i++)
comb[i] = i;
but I have trouble with the routine that exludes certain combinations. The routine is
int todel (int comb[], int k)
{
int i, j, seq;
for (i = 0, seq = 0; (i+maxp) < k; i++)
{
int j = 0;
for (j = i; j < maxp; j++)
{
fprintf(stderr, "checkin comb %d with comb %d\n", j, j+1);
if (comb[j] == (comb[j+1] - 1))
{
seq++;
}
if (seq >= maxp) return 1;
}
}
return 0;
}
if I have a set of 10 a subset of 10 and a max allowed of 10, the program does not need to exlude anything.
But for a set 10 subset 9 and a max allowed of 1 the program should exclude all 10 combinations. But as it is the program is allowing the following combination
0,2,3,4,5,6,7,8,9
and it should exclude it because 0,2 does not match the criteria, 2,3 and all thw following does.
Another thing is that if I set the maximum allowed to 0 it takes all combinations as valid instead of none.
I know the fix should not be very hard and I am missing something really dumb.
I hope some insight from you (probably insults too).
Thank you !
I was working on a program for my intro to C class (xtra credit assignment) and can't figure out how to discard duplicates numbers on an array. The problem asks to only print non duplicates; so I able to print the first number, compare the following and print if different, I discard the next if a duplicate, but the thing is I've only figured out how to compare the one number it following one, I figured I could do another for loop inside the for loop, but I'm getting super confused and just can't figure it out. I've already submitted my code last week, I've just been working on this trying to figure it out for myself so any help/guidance would be greatly appreciated.
"EDIT: Here's the problem: Use a single-subscripted array to solve the following problem. Read in 20 numbers, each of which is between 10 and 100, inclusive. As each number is read, print it only if it's not a duplicate of a number already read. Provide for the worst case in which all 20 numbers are different. Use the smallest possible array to solve this problem"
Thanks in advance, and any advice on how I'm writing my program would also be appreciated as I'm a total noob, and trying to be a good programmer with as little bad habits as possible.
#include <stdio.h>
#include <stdlib.h>
#define AS 20
void findDuplicate (int af[], int fAS);
int main(){
int a[AS], i , j, k;
int last = 0;
printf("Enter %d numbers between 10 and 100:\n", AS);
for (i = 0; i < AS; i++){
scanf("%d",&a[i] );
if (a[i] >= 10 && a[i] <= 100 ){
continue;
} else {
printf("You must enter values between 10 - 100\n");
i = i -1;
}
}
findDuplicate(a, AS);
system ("pause");
return 0;
}
void findDuplicate (int af[], int fAS){
int c;
printf("You entered ");
for (c=0; c < fAS; c++){
if (af[c] != af[c+1]){
printf("%d ", af[c]);
}
continue;
}
printf("\n");
}
You should first define an Array which can save as many variables as you want ..
Lets say you are comparing for 10-100 which means 91 possible different digits.
so , define array with the size of 91. and then do the scanning in for loop for 91 times to find out if you have that variable entered previously. If not then save it and display it ,else discard it.
I've got a c study which it must print all the numbers in an array then how many times they repeated.
int lottery(int a,int b,int c,int d,int e,int f,int i,int count)
{
printf("Enter the loop count:");
scanf("%d",&d);
a=time(NULL);
srand(a);
int genel[100][100];
int hepsi[50]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49};
count=0;
for(e=0;e<=d-1;e++)
{
for(b=0;b<=5;b++)
{
genel[e][b]=(rand()%49+1);
while(i>=0 && i<=49)
{
if(genel[e][b]==hepsi[i])
{
count=count+1;
}
else{
count=count;
}
}
printf("%d->%d\t",genel[e][b],count);
}
}
}
This doesnt work obviously. the output must be something like that
1-->0 2-->3 3-->15 etc
TY for your help, cheers :)
It is important that you understand what you are doing, naming is therefore very important. Nesting loops is okay if you know what you are doing. An easier to understand approach would be:
void lottery() {
int i, j //forloop counters
int randArray[100][100]; //array for random values
srand(Time(NULL)); //set random seed based on system time
//set random values
for(i = 0; i < 100; i++) {
for(j = 0; j < 100; j++) {
randArray[i][j] = rand()%49 + 1; //sets random ranging from 1 to 49 (49 incl)
}
}
//here you can start the counting procedure, which I won't spoil but ill give some hints below
}
There are a few options, first the easy lazy approach:
use a loop over all the values, 'int number' from 1 up to 49, inside that forloop use two forloops to search through the whole array, incrementing int x everytime you encounter the value 'number'. After youve searched through the whole array, you can use printf("%d -> %d", number, x); to print the value, set x to zero and count another number.
Another approach is as u tried,
create an array with for each number a location where you can increment a counter. Loop through the whole array now using two for-loops, increment the arraylocation corresponding to the value which youve found at randArray[i][j]. Afterwards print the array with counts using another forloop.
I suggest you try to clean up your code and approach, try again and come back with problems you encounter. Good luck!
sorry if this wasn't helpful to you, I tried to spoil not too much because according to my own experience programming should be learned by making mistakes.