I'm doing an online course on "Programming, Data Structure & Algorithm". I've been given an assignment to "find the most frequent element in a sequence using arrays in C (with some constraints)". They've also provided some test-cases to verify the correctness of the program. But I think I'm wrong somewhere.
Here's the complete question from my online course.
INPUT
Input contains two lines. First line in the input indicates N,
the number of integers in the sequence. Second line contains N
integers, separated by white space.
OUTPUT
Element with the maximum frequency. If two numbers have the
same highest frequency, print the number that appears first in the
sequence.
CONSTRAINTS
1 <= N <= 10000
The integers will be in the range
[-100,100].
And here's the test cases.
Test Case 1
Input:
5
1 2 1 3 1
Output:
1
Input:
6
7 7 -2 3 1 1
Output:
7
And here's the code that I've written.
#include<stdio.h>
int main()
{
int counter[201] = {0}, n, i, input, maximum = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++) {
scanf("%d", &input);
if(input < -100 && input < 100)
++counter[input];
}
maximum = counter[0];
for (i = 1; i < 201; i++) {
if (counter[i] > maximum) {
maximum = counter[i];
}
}
printf("%d", maximum);
return 0;
}
Please tell me where I'm wrong. Thank you.
EDIT:
I've modified the code, as suggested by #zoska. Here's the working code.
#include<stdio.h>
int main()
{
int counter[201] = {0}, n, i, input, maximum = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++) {
scanf("%d", &input);
if(input < 100 && input > 0)
++counter[input + 100];
else
++counter[input];
}
maximum = counter[0];
for (i = 0; i < 201; i++) {
if (counter[i] > maximum) {
maximum = i - 100;
}
}
printf("%d", maximum);
return 0;
}
Additionally to problem pointed out by Paul R is:
You are printing maximum occurrences of number, not the number itself.
You're going to need another variable, which will store the number with maximum occurences. Like :
maximum = count[0];
int number = -100;
for (i = 0; i < 201; i++) {
if (counter[i] > maximum) {
maximum = counter[i];
number = i - 100;
}
}
printf("number %d has maximum occurences: %d", number, maximum);
Also you should iterate through an array from 0 to size-1:
So in all cases of your loops it should be :
for(i = 0; i < 201; i++)
Otherwise you won't be using count[0] and you will only have a range of -99...100.
Try below code
#include<stdio.h>
int main()
{
int counter[201] = {0}, n, i, input, maximum = 0;
scanf("%d", &n);
for(i = 1; i <= n; i++) {
scanf("%d", &input);
if(input >= -100 && input <= 100)
++counter[input + 100];
}
maximum = counter[0];
int index = 0;
for (i = 0; i < 201; i++) {
if (counter[i] >= maximum) {
index = i;
maximum = counter[i];
}
}
printf("number %d occured %d times\n", index-100, maximum);
return 0;
}
I would prefer checking in one loop itself for the maximum value just so that the first number is returned if i have more than one element with maximum number of occurances.
FInd the code as:
#include<stdio.h>
int main()
{
int n,input;
scanf("%d",&n);
int count[201] ={0};
int max=0,found=-1;
for(int i=0;i<n;i++)
{
scanf("%d",&input);
count[input+100]++;
if(max<count[input+100])
{
max= count[input+100];
found=input;
}
}
printf("%d",found);
return 0;
}
But, there is also one condition that if the number of occurance are same for two numbers then the number which appers first in sequence should appear.
Related
In my code, the program will not allowed the negative number entered, the program will stop reading, then calculate the maximum value, minimum value and average value.
That is my code
#include <stdio.h>
int main(void) {
int age[10] = {0}; // initalized an array
printf("Please enter ages: \n"); // allow user to enter numbers
for (int i = 0 ;i < 10; i++) {
scanf("%d",&age[i]);
if (age[i] < 0) { // if it is negative number, it is should stop reading
break;
}
else if (age[i] >= 0) {
continue;
}
}
int maximum = age[0];
int minimum = age[0];
float average = 0.0;
int length = sizeof(age) / sizeof(age[0]);
for (int j = 0; j < length; j++) {
if (maximum < age[j]) {
maximum = age[j];
}
else if (minimum > age[j]) {
minimum = age[j];
}
average += age[j];
}
average = average / length;
printf("%d\n", maximum);
printf("%d\n", minimum);
printf("%.1f\n", average);
return 0;
}
Please enter ages: 5 -1
expected result: max:5;min:5,average:5;
actual result: max:5;min:-1,average: 0.4;
That was a question that I met, the code should not accept any negative value.
Thank you all.
but if I add age[i] = 0; then break;
The average value will equal to 0.5.
You don't need an array.
You don't need both a loop variable and a length.
It's more appropriate to use ? : for updating minimum/maximum.
You don't need two loops
You need to check the int return value of scanf(), which indicates the number of items successfully scanned, so it should be 1. I'll leave that for you/OP to add (hint: replace for-loop by while-loop to avoid having to add a separate length variable again).
int main(void)
{
printf("Please enter ages: \n");
int minimum = INT_MAX;
int maximum = 0;
int sum = 0;
int count = 0;
for (count = 0; count < 10; count++)
{
int age;
scanf("%d", &age);
if (age < 0)
{
break;
}
sum += age;
minimum = (age < minimum) ? age : minimum;
maximum = (age > maximum) ? age : maximum;
}
if (count > 0)
{
printf("Min: %d\n", minimum);
printf("Max: %d\n", maximum);
printf("Avg: %.1f\n", (float)sum / count);
}
else
{
printf("You didn't enter (valid) age(s).\n");
}
return 0;
}
Your approach is overly complicated and wrong.
You want this:
...
int length = 0; // declare length here and initialize to 0
for (int i = 0; i < sizeof(age) / sizeof(age[0]); i++) {
scanf("%d", &age[i]);
if (age[i] < 0) // if it is negative number, it is should stop reading
break;
length++; // one more valid number
}
// now length contains the number of numbers entered
// the rest of your code seems correct
You also might need to handle the special case where no numbers are entered, e.g: the only thing entered is -1. It doesn'make sense to calculate the average or the largest/smallest number when there are no numbers.
A possible solution could be:
(corrections are written in the commented code)
#include <stdio.h>
int main(void){
int arraySize = 10;
int age[arraySize]; //initialize not required
//the number of existing values inside the array (effective length)
int length = 0;
printf("Please enter ages: \n"); // allow user to enter numbers
for(int i=0; i<arraySize; i++){
scanf("%d",&age[i]);
// if it is negative number, it is should stop reading
if(age[i]<0){ break; }
//the else-if is not required
//but, if the compiler goes here,
//it means that the value is acceptable, so
length++;
}
int maximum = age[0];
int minimum = age[0];
float average = 0.0;
for(int j=0; j<length; j++){
if(maximum<age[j]){ maximum = age[j]; }
else if(minimum>age[j]) { minimum = age[j]; }
average += age[j];
}
average = average / length;
printf("%d\n", maximum);
printf("%d\n", minimum);
printf("%.1f\n", average);
return 0;
}
OP's primary problem is the 2nd loop iterates 10 times and not i times (the number of times a non-negative was entered.
For fun, let us try a non-floating point solution as it really is an integer problem.
An array to store values is not needed.
#include <limits.h>
#include <stdio.h>
int main(void) {
// Keep track of 4 things
int min = INT_MAX; // Set min to the max int value.
int max = INT_MIN;
long long sum = 0; // Use wide type to cope with sum of extreme ages.
int count = 0;
#define INPUT_N 10
printf("Please enter ages: \n");
for (count = 0; count < INPUT_N; count++) {
int age;
if (scanf("%d", &age) != 1) {
fprintf(stderr, "Missing numeric input.");
return EXIT_FAILURE;
}
if (age < 0) {
break;
}
if (age < min) min = age;
if (age > max) max = age;
sum += age;
}
if (count == 0) {
fprintf(stderr, "No input.");
return EXIT_FAILURE;
}
printf("Maximum: %d\n", max);
printf("Minimum: %d\n", min);
// Could use FP and
// printf("Average: %.1f\n", 1.0 *sum / count);
// But for fun, how about a non-FP approach?
#define SCALE 10
#define SCALE_LOG 1
sum *= SCALE; // Scale by 10 since we want 1 decimal place.
// Perform a rounded divide by `count`
long long average_scaled = (sum + count/2) / count;
// Print the whole and fraction parts
printf("Average: %lld.%.*lld\n",
average_scaled / SCALE, SCALE_LOG, average_scaled % SCALE);
return 0;
}
First of all, you must record how many positive numbers you enter. Then the value of length will be correct.
Second, for the second for loop, j must be smaller than the number of positive ages. Therefore, you won't add negative age[j] to average.
You can simply modify the second for loop.
#include <stdio.h>
int main(void) {
int age[10] = {0}; // initalized an array
printf("Please enter ages: \n"); // allow user to enter numbers
int length = 0;
for (int i = 0 ;i < 10; i++) {
scanf("%d",&age[i]);
if (age[i] < 0) { // if it is negative number, it is should stop reading
break;
}
else if (age[i] >= 0) {
length++;
continue;
}
}
int maximum = age[0];
int minimum = age[0];
float average = 0.0;
for (int j = 0; j < length; j++) {
if (maximum < age[j]) {
maximum = age[j];
}
else if (minimum > age[j]) {
minimum = age[j];
}
if ( age[j] > 0.0 )
{
average += age[j];
}
}
average = average / length;
printf("%d\n", maximum);
printf("%d\n", minimum);
printf("%.1f\n", average);
return 0;
}
I need to write a program that allows user to enter an array of integers, finds the digit that appears most often in all entered numbers, and removes it from the elements of the array. If several digits appear the same number of times, the smallest of them should be deleted. If all digits of the element of the array are deleted, that element should become zero. In the end, such a modified array is printed.
Example of input and output:
Enter number of elements of the array: 5
Enter the array: 3833 8818 23 33 1288
After deleting, the array is: 8 8818 2 0 1288
Explanation: The numbers 3 and 8 appear the same number of times (6 times each), but 3 is less, so it was removed it from all members of the array. Element 33 consists exclusively of the digits 3, so that it becomes 0.
#include <stdio.h>
int main() {
int i,n,arr[100]; n;
printf("Enter number of elements of the array: ");
scanf("%d", &n);
printf("Enter the array: ");
for(i=0;i<n;i++) {
scanf("%d", &arr[i]);
}
return 0;
}
EDIT: I'm beginner to programming, and this task should be done using only knowledge learned so far in my course which is conditionals, loops, and arrays. This shouldn't be done with strings.
Divide the problem into separate tasks.
Write the code
In the code below I do not treat 0 as having digit 0. It is because it is not possible to remove 0 from 0. You can easily change this behaviour by changing while(){} loop to do{}while()
int removeDigit(int val, int digit)
{
int result = 0;
unsigned mul = 1;
int sign = val < 0 ? -1 : 1;
digit %= 10;
while(val)
{
int dg = abs(val % 10);
if(dg != digit)
{
result += dg * mul;
mul *= 10;
}
val /= 10;
}
return sign * result;
}
void countDigits(int val, size_t *freq)
{
while(val)
{
freq[abs(val % 10)]++;
val /= 10;
}
}
int findMostFrequent(const size_t *freq)
{
size_t max = 0;
for(size_t i = 1; i < 10; i++)
{
if(freq[i] > freq[max]) max = i;
}
return (int)max;
}
int main(void)
{
int table[20];
size_t freq[10] = {0,};
int mostfreq = 0;
srand(time(NULL));
for(size_t i = 0; i < 20; i++)
{
table[i] = rand();
printf("Table[%zu] = %d\n", i, table[i]);
countDigits(table[i], freq);
}
mostfreq = findMostFrequent(freq);
printf("Most frequent digit: %d\n", mostfreq);
for(size_t i = 0; i < 20; i++)
{
table[i] = removeDigit(table[i], mostfreq);
printf("Table[%zu] = %d\n", i, table[i]);
}
}
https://godbolt.org/z/PPj9s341b
I'm supposed to do a freqency analysis of a user input array. User may enter as many numbers between 0-1000 as s/he wants and a maximum of 100 numbers can be entered, user ends input by entering a negative number. A void function will calculate which number appears the most times and those 2 variables should be sent to the function as pointers.
My problem is that no matter what I do the analysis seems to calculate all the "empty" elements of the array and I can't figure out what I'm doing wrong. If i make the array smaller to lets say 10 elements it works fine. As I'm a complete novice when it comes to programming and I've changed the code about a million times so at this point I can't remeber what I've changed from my original code. When debugging I get stuck in the second for loop in the function..
#include <stdio.h>
#define MAX 100
#define INTERVAL 1000
void frequencyAnalysis(int array[],int *number, int *freq)
{
int element = 0, count = 0;
for (int i = 0; i < MAX; i++) {
int tempElement = array[i];
int tempCount = 0;
for (int j = 0; j < MAX; j++)
if (array[j] == tempElement)
tempCount++;
if (tempCount > count) {
element = tempElement;
count = tempCount;
}
}
*number = element;
*freq = count;
}
int main(void)
{
int array[MAX], i, j, number = 0, freq = 0;
printf("Hello.\n"
"Please enter a number between 0-1000. "
"Enter as many number as you want (maximum 100).\n"
"Exit by entering a negative number.\n\n");
printf("Enter a number:\n");
for (i = 0; i < MAX; i++) {
scanf("%d", &array[i]);
if (array[i] < 0)
break;
}
frequencyAnalysis(array, &number, &freq);
printf("The number:%d is the most frequent number and appears %d times.\n", number, freq);
return 0;
}
Addressing the first issue, pass in how many items the user actually entered so you're not running up to MAX (which would include all the unused cells). The key is nitems.
void frequencyAnalysis(int array[], int nitems, int *number, int *freq)
{
for (int i = 0; i < nitems; i++) {
...
for (int j = 0; j < nitems; j++)
{
// do stuff
}
}
}
int main(void)
{
int array[MAX],i, j, number = 0, freq = 0;
...
frequencyAnalysis(array, i, &number,&freq);
///
}
Can you help me find out why the second 0 in the array turns into 45 please.
Everything is okay but except this number makes the result goes wrong. I cannot find out what's the matter with this.
Here is my code:
#include <stdio.h>
int getuserchoice() {
int n;
printf("---ISBN Validate---");
printf("\n1-ISBN Checking");
printf("\n2-Quit");
printf("\nSelect: ");
scanf("%d", &n);
return n;
}
int main() {
long a[10];
long sum = 0;
int i = 0, n = 1;
long x;
if (getuserchoice() == 1) {
printf("\nEnter the values for ISBN number : ");
scanf("%ld", &x);
if (x > 0) {
while (x > 0) {
a[i] = x % 10;
x = x / 10;
i++;
}
}
for (i = 0; i < 10; i++)
printf("%ld\t", a[i]);
for (i = 0; i < 10; i++) {
sum += a[i] * n;
n++;
}
if (sum % 11 == 0)
printf("\nISBN Status: Valid!");
else
printf("\nISBN Status: Invalid!");
} else
printf("\nSee you later!");
getchar();
return 0;
}
By default uninitialized arrays contain garbage (literally anything). It so happens that that particular element contains 45 (amazing, isn't it?).
It stays 45 because leading 0s are discarded when reading a number (you should read it as a string (C++) or char[]), so you are never accessing that particular array element to give it a meaningful value.
Here's SO post on how to initialize an array with 0s in C.
Build a program which reads from the user an array with n elements and finds the element with the smallest value.Then the program finds the number of the elements which have an equal value with this minimum.The found element with the smallest value along with the number of the elements which have an equal value with the minimum of the array should be displayed on screen..
I wrote this code :
#include <stdio.h>
int main() {
int n = 1, min = 0, count = 0;
int number[n];
printf("Enter the size of array you want");
scanf("%i", &n);
int x;
for (x = 0; x < n; x++) {
int num;
printf("\nEnter a Integer");
scanf("%i", &num);
number[x] = num;
if (number[x] < min)
min = number[x];
}
int i;
for (i = 0; i < n; i++) {
if (min = number[i])
count++;
}
printf("%s%i", "\nThe smallest Integer you entered was ", min);
printf("%s%i", "\nNumber of times you entered this Integer: ", count);
return 0;
}
But the problem is that when I run this,and I add the integers,it doesnt find the smallest value and how time its repeated correctly!
Where am I wrong?
Assuming your compiler has support for variable length arrays, you need to re-order the calls
int number[n];
scanf("%i", &n);
so that you know the value for n before declaring the array
scanf("%i", &n);
int number[n];
After that, you should initialise min to a larger value to avoid ignoring all positive values
int min = INT_MAX;
(You'll need to include <limits.h> for the definition of INT_MAX)
Finally,
if (min = number[i])
assigns number[i] to min. Use == to test for equality.
Your compiler should have warned you about "assignment in conditional statement" for this last point. If it didn't, make sure you have enabled warnings (-Wall with gcc, /W4 with MSVC)
you are checking array element <0 in line:
if (number[x] < min/*as u specified min =0 before*/),...
so the minimum is set to be zero and there is no replacement actually happening..
The full solution:
#include <stdio.h>
int main() {
int n = 1, min = 0, count = 0;
int number[n];
printf("Enter the size of array you want");
scanf("%i", &n);
int x,y;
for (y = 0; y < n; y++)
{
printf("\nEnter a Integer");
scanf("%i", &number[y]);
}
min=number[0];
for (x = 0; x < n; x++) {
if (number[x] < min)
min = number[x];
}
int i;
for (i = 0; i < n; i++) {
if (min == number[i])
count++;
}
printf("%s%i", "\nThe smallest Integer you entered was ", min);
printf("%s%i", "\nNumber of times you entered this Integer: ", count);
return 0;
}
for (i = 0; i < n; i++) {
if (min = number[i])
count++;
}
Replace min = number[i] with min == number[i].
1.Only After the user input the array size, then you can determine the size of the array number.As the size of the array are uncertain, you should use malloc to allocate the array dynamically.
2.you should set min to the first element of the array. As the min of user input may be great than zero, if you set min to zero, then it will return zero even though the minimum is great than zero
3.you should use == but not = to test the equality of two numbers.
4.last, you should use free to make the memory available and avoid memory leak.
Below is the full program:
#include <stdio.h>
int main() {
int n = 1, min = 0, count = 0;
int* number;
printf("Enter the size of array you want");
scanf("%i", &n);
number = (int*)malloc(sizeof(int)*n);
int x;
for (x = 0; x < n; x++) {
int num;
printf("\nEnter a Integer");
scanf("%i", &num);
number[x] = num;
if( x == 0 || number[x] < min )
min = number[x];
}
int i;
for (i = 0; i < n; i++) {
if (min == number[i])
count++;
}
printf("%s%i", "\nThe smallest Integer you entered was ", min);
printf("%s%i", "\nNumber of times you entered this Integer: ", count);
free(number);
number = NULL;
return 0;
}
In your code
if (min = number[i])
you assigned number[i] to min. You should write
if (min == number[i])
instead.
There are couple of things wrong on your code. First you defined array number[1]. Secondly min in initialised to min = 0.
I suggest defined the array for a maximum possible size, like number[100]. And read the numbe of inputs n from the user, and only use the first n elements of the array. For the second issue, define min as the maximum number represented by int type.