find the most frequent number in an array - c

I've recently started learning C and I ran into this small test.
Make a code which reads 10 numbers from a user.
Print the Largest & Smallest entered values then print the most frequent number.
Making everything was simple for me but the most-frequent number is driving me crazy, I've searched for awhile and couldn't find any clear answers.
The code I wrote
#include <stdio.h>
#include <stdlib.h>
int main()
{
int hi[10], i=0, largest, smallest;
while(i<10)
{
printf("Enter a number:");
scanf("%d", &hi[i]);
i++;
}
smallest = hi[0];
largest = hi[0];
printf("Entered Numbers: ");
while(i!=0)
{
if(hi[10-i] < smallest) { smallest = hi[10-i]; }
if(hi[10-i] > largest) { largest = hi[10-i]; }
printf("%d | ", hi[10-i]);
i--;
}
printf("\nLargest number is = %d || Smallest number is = %d", largest, smallest);
return 0;
}
The only idea I thought of was:
Making another array.
Getting value of [i] in the original array.
Compare [i] with rest of values of original array (if they are equal or not).
Increment the value of the other array if they are equal.
Check largest value in the other array and that should be most frequent number.
Now, I know the order of most frequent element and how many times that element was entered.

Using a hashmap would be more efficient. There you can use the input number as key and set the value to 1. When a new number was given by the user, you just have to check wether the new number is already in the map. If so, you set the value to two, otherwise you add the new number with the value 1.

Piggy backing on what Markus said, a hash map really is ideal for a universal solution so you can keep the asymptotic time down, but since you're only doing an array of 10, using a 2D array to store the frequency will work just fine.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int hi[10][2], i=0,j=0,largest, smallest;
while(i<10)
{
printf("Enter a number:");
scanf("%d", &hi[i][0]);
i++;
}
smallest = hi[0][0];
largest = hi[0][0];
printf("Entered Numbers: ");
while(i!=0)
{
hi[10-i][1] = 0;
if(hi[10-i][0] < smallest) { smallest = hi[10-i][0]; }
if(hi[10-i][0] > largest) { largest = hi[10-i][0]; }
printf("%d | ", hi[10-i][0]);
i--;
}
int most_freq = 0;
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
if(hi[i][0] == hi[j][0]){
hi[i][1]++;
if (hi[i][1] > most_freq){
most_freq = hi[i][0];
}
}
}
}
printf("\nLargest number is = %d || Smallest number is = %d", largest, smallest);
printf("\nMost frequent is = %d\n", most_freq);
return 0;
}

Related

C program to read 'n' numbers and find out the sum of odd valued digits of each number and print them

i am new to programing, i want to know that how we can find the odd digits in a number.
the condition in this program is we should only use concept of arrays.I tried a code for this as follows:
#include <stdio.h>
int main()
{
int A[50],i,x,y,n,sum=0;
scanf("%d",&n);
printf("the value is %d\n",n);
for(i=0;i<n;i++)
scanf("%d",&A[i]);
for(i=0;i<n;i++){
x=A[i]%10;
if(x%2!=0)
sum=sum+x;
A[i]=A[i]/10;
printf("the sum of odd numbers is %d\n",sum);
}
return 0;
}
but in this the code is checking for only one digit of the first number in the loop and then next time it is going to check the digit of second number.
so, i need to write a code to check all digits in the number and then it goes to next number and check all digits and should continue the same process in the loop.So, for this how should i modify my code?
You were missing a loop that would iterate through every digit of A[i] - the inner while loop below,
#include <stdio.h>
int main()
{
int A[50], i, x, y, n, sum=0;
printf("How many numbers will you input?\n");
scanf("%d",&n);
printf("the value is %d\n",n);
for(i=0; i<n; i++) {
scanf("%d",&A[i]);
}
for(i=0; i<n; i++) {
sum = 0;
while (A[i] > 0) {
x = A[i]%10;
if(x%2 != 0) {
sum = sum + x;
}
A[i] = A[i]/10;
}
printf("the sum of odd numbers is %d\n",sum);
}
return 0;
}
The exact algorithm for iterating through each digit in a nice form can be found in this post - although for a different language. Here, apart from the while loop, you also need to reset the sum each time unless you want a cumulative sum over all provided numbers.
Note that I changed the formatting a bit - more space, extra braces, and a message about what you're prompting the user to input.
int temp;
int sum = 0;
temp = number;
do {
lastDigit = temp % 10;
temp = temp / 10;
sum += (lastDigit %2 != 0) ? lastDigit : 0;
} while(temp > 0);

Basic While Loop Precedence (C)

I'm new to coding and am learning C. I just had a question regarding while loops.
#include <stdio.h>
int main(void) {
int integer1, integer2, number, sum, largest, smallest;
float average;
integer1 = 0;
number = 0;
sum = 0;
largest = integer1;
smallest = integer1;
while (integer1 != -1) {
printf("Enter the number: ");
scanf_s("%d", &integer1);
number++;
sum = sum + integer1;
if (integer1 >= largest) {
largest = integer1;
}
if (integer1 <= smallest) {
smallest = integer1;
}
}
average = (float) sum / number;
printf("The number of user's input: %d.\n", number);
printf("The sum of input numbers: %d.\n", sum);
printf("The average of input numbers: %.2f.\n", average);
printf("The largest number is: %d.\n", largest);
printf("The smallest number is %d.\n", smallest);
return 0;
}
The objective of the code I've written is to:
Read integer values from the user.
Terminate the while loop when the user enters '-1'.
Output the printf statements with their corresponding values.
Here's the problem: All of the integer variables that I've declared should NOT include the value of '-1; inputted by the user. I assume that this has to do with an issue of precedence regarding the while loop, but I can't seem to pinpoint what it is. Any help or insight is greatly appreciated.
Thank you!
Sometimes neither while nor do/while loop fit your needs, because the decision to exit the loop must be made in the middle of loop's body.
Reading values and deciding what to do after the read presents one of such situations. A common solution is to set up an infinite loop, and exit it from the middle on a break:
for (;;) {
printf("Enter the number: ");
scanf_s("%d", &integer1);
if (integer1 == -1) {
break;
}
... // The rest of your code
}
In order to achieve what you want you need to add one line.
//use infinite loop
while (1) {
printf("Enter the number: ");
scanf_s("%d", &integer1);
//jump out of the loop because the loop has already started.
//but the value was -1
if (integer == -1) break;
number++;
sum = sum + integer1;
if (integer1 >= largest) {
largest = integer1;
}
if (integer1 <= smallest) {
smallest = integer1;
}
}
Just add your scanf() statement prior to your while loop.

How to compare the digits of 2 integer numbers in c (without arrays and strings)

I am making simple example of little game about guessing numbers.
And I want to build a function which check the numbers and make two values as follows:
1) hits-the number of digits that contain in both number and in same place for both numbers.
2) misses-the number of the digits which contain in both number but not in the same place.
For example:
int systemNumber=1653;
int userGuess=5243;
in this example, in both numbers there are the digits 5 and 3. In both numbers the digit 3 in the same place. But, the digit 5 in systemNumber is not in the same place as userNumber. So, we have here 1 hit and 1 miss.
I've written the code for it with arrays, and I'd like to know if there is a way that I will be able to do this without array and strings.
Here is my code. Please, if you have any improvement for my code, I'd like to know it :)
#include <stdio.h>
#include <stdlib.h>
void checkUserCode(int num1[4], int num2[4]); // declare the function which check the guess
int hits=0, misses=0; // hits and misses in the guess
int main(void)
{
int userCode=0;
int userCodeArray[4];
int systemCodeArray[4]={1, 4, 6, 3};
int i=0;
// printing description
printf("welcome to the guessing game!\n");
printf("your goal is to guess what is the number of the system!\n");
printf("the number have 4 digits. Each digit can be between 1 to 6\nGood Luck!\n");
// input of user guess
printf("enter number: ");
scanf("%d", &userCode);
for (i=3; i>=0; i--)
{
userCodeArray[i]=userCode%10;
userCode=userCode/10;
}
checkUserCode(systemCodeArray, userCodeArray);
printf("there are %d hits and %d misess", hits, misses); // output
return 0;
}
/*
this function gets two arrays and check its elements
input (parameters): the two arrays (codes) to check
output (returning): number of hits and misses
if the element in one array also contains in the other array but not the same index: add a miss
if the element in one array also contains in the other array and they have the same index: add a hits
*/
void checkUserCode(int num1[4], int num2[4])
{
int i=0, j=0;
for (i=0; i<4; i++)
{
for (j=0; j<4; j++)
{
if(num1[i]==num2[j])
{
if (j==i)
hits++;
else
misses++;
}
}
}
}
Here is an example I wrote a while ago, which I tweaked for your problem:
I basically uses two for loops, the outer loop going over the first number, 1653, and the inner loop going over the second number, 5243. It basically compares each individual number in the first number against all the numbers in the second number.
Depending on the counters, it evaluates if equal numbers have been matched in the same positions, using modulo %10 to compare each number.
This is the code:
#include <stdio.h>
#include <stdlib.h>
int
main(void) {
int num1 = 1653;
int num2 = 5243;
int pos1, pos2, hit = 0, miss = 0, i, j;
pos1 = 0;
for (i = num1; i > 0; i /= 10) {
pos2 = 0;
for (j = num2; j > 0; j /= 10) {
if (i % 10 == j % 10) {
if (pos1 == pos2) {
hit++;
} else {
miss++;
}
}
pos2++;
}
pos1++;
}
printf("hits = %d\n", hit);
printf("misses = %d\n", miss);
return 0;
}

Returning to the start of a for loop in C

Even though this question has been asked a million times I just haven't found an answer that actually helps my case, or I simply can't see the solution.
I've been given the task to make a program that takes in a whole number and counts how many times each digit appears in it and also not showing the same information twice. Since we're working with arrays currently I had to do it with arrays of course so since my code is messy due to my lack of knowledge in C I'll try to explain my thought process along with giving you the code.
After entering a number, I took each digit by dividing the number by 10 and putting those digits into an array, then (since the array is reversed) I reversed the reverse array to get it to look nicer (even though it isn't required). After that, I have a bunch of disgusting for loops in which I try to loop through the whole array while comparing the first element to all the elements again, so for each element of the array, I compare it to each element of the array again. I also add the checked element to a new array after each check so I can primarily check if the element has been compared before so I don't have to do the whole thing again but that's where my problem is. I've tried a ton of manipulations with continue or goto but I just can't find the solution. So I just used **EDIT: return 0 ** to see if my idea was good in the first place and to me it seems that it is , I just lack the knowledge to go back to the top of the for loop. Help me please?
// With return 0 the program stops completely after trying to check the digit 1 since it's been checked already. I want it to continue checking the other ones but with many versions of putting continue, it just didn't do the job. //
/// Tried to make the code look better. ///
#include <stdio.h>
#define MAX 100
int main()
{
int a[MAX];
int b[MAX];
int c[MAX];
int n;
int i;
int j;
int k;
int counter1;
int counter2;
printf("Enter a whole number: ");
scanf("%i",&n);
while (1)
{
for (i=0,counter1=0;n>10;i++)
{
a[i] = n%10;
n=n/10;
counter1+=1;
if (n<10)
a[counter1] = n;
}
break;
}
printf("\nNumber o elements in the array: %i", counter1);
printf("\nElements of the array a:");
for (i=0;i<=counter1;i++)
{
printf("%i ",a[i]);
}
printf("\nElements of the array b:");
for (i=counter1,j=0;i>=0;i--,j++)
{
b[j] = a[i];
}
for (i=0;i<=counter1;i++)
{
printf("%i ",b[i]);
}
for (i=0;i<=counter1;i++)
{
for(k=0;k<=counter1;k++)
{
if(b[i]==c[k])
{
return 0;
}
}
for(j=0,counter2=0; j<=counter1;j++)
{
if (b[j] == b[i])
{
counter2+=1;
}
}
printf("\nThe number %i appears %i time(s)", b[i], counter2);
c[i]=b[i];
}
}
The task at hand is very straightforward and certainly doesn't need convoluted constructions, let alone goto.
Your idea to place the digits in an array is good, but you increment counter too early. (Remember that arrays in C start with index 0.) So let's fix that:
int n = 1144526; // example number, assumed to be positive
int digits[12]; // array of digits
int ndigit = 0;
while (n) {
digits[ndigit++] = n % 10;
n /= 10;
}
(The ++ after ndigit will increment ndigit after using its value. Using it as array index inside square brackets is very common in C.)
We just want to count the digits, so reversing the array really isn't necessary. Now we want to count all digits. We could do that by counting all digits when we see then for the first time, e.g. in 337223, count all 3s first, then all 7s and then all 2s, but that will get complicated quickly. It's much easier to count all 10 digits:
int i, d;
for (d = 0; d < 10; d++) {
int count = 0;
for (i = 0; i < ndigit; i++) {
if (digit[i] == d) count++;
}
if (count) printf("%d occurs %d times.\n", d, count);
}
The outer loop goes over all ten digits. The inner loop counts all occurrences of d in the digit array. If the count is positive, write it out.
If you think about it, you can do better. The digits can only have values from 0 to 9. We can keep an array of counts for each digit and pass the digit array once, counting the digits as you go:
int count[10] = {0};
for (i = 0; i < ndigit; i++) {
count[digit[i]]++;
}
for (i = 0; i < 10; i++) {
if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}
(Remember that = {0} sets the first element of count explicitly to zero and the rest of the elements implicitly, so that you start off with an array of ten zeroes.)
If you think about it, you don't even need the array digit; you can count the digits right away:
int count[10] = {0};
while (n) {
count[n % 10]++;
n /= 10;
}
for (i = 0; i < 10; i++) {
if (count[i]) printf("%d occurs %d times.\n", i, count[i]);
}
Lastly, a word of advice: If you find yourself reaching for exceptional tools to rescue complicated code for a simple task, take a step back and try to simplify the problem. I have the impression that you have added more complicated you even you don't really understand instead.
For example, your method to count the digits is very confused. For example, what is the array c for? You read from it before writing sensible values to it. Try to implement a very simple solution, don't try to be clever at first and go for a simple solution. Even if that's not what you as a human would do, remeber that computers are good at carrying out stupid tasks fast.
I think what you need is a "continue" instead of a return 0.
for (i=0;i<=counter1;i++) {
for(k=0;k<=counter1;k++) {
if(b[i]==c[k]) {
continue; /* formerly return 0; */
}
for(j=0,counter2=0; j<=counter1;j++)
if (b[j] == b[i]){
counter2+=1;
}
}
Please try and see if this program can help you.
#include <stdio.h>
int main() {
unsigned n;
int arr[30];
printf("Enter a whole number: ");
scanf("%i", &n);
int f = 0;
while(n)
{
int b = n % 10;
arr[f] = b;
n /= 10;
++f;
}
for(int i=0;i<f;i++){
int count=1;
for(int j=i+1;j<=f-1;j++){
if(arr[i]==arr[j] && arr[i]!='\0'){
count++;
arr[j]='\0';
}
}
if(arr[i]!='\0'){
printf("%d is %d times.\n",arr[i],count);
}
}
}
Test
Enter a whole number: 12234445
5 is 1 times.
4 is 3 times.
3 is 1 times.
2 is 2 times.
1 is 1 times.
Here is another offering that uses only one loop to analyse the input. I made other changes which are commented.
#include <stdio.h>
int main(void)
{
int count[10] = { 0 };
int n;
int digit;
int elems = 0;
int diff = 0;
printf("Enter a whole number: ");
if(scanf("%d", &n) != 1 || n < 0) { // used %d, %i can accept octal input
puts("Please enter a positive number"); // always check result of scanf
return 1;
}
do {
elems++; // number of digits entered
digit = n % 10;
if(count[digit] == 0) { // number of different digits
diff++;
}
count[digit]++; // count occurrence of each
n /= 10;
} while(n); // do-while ensures a lone 0 works
printf("Number of digits entered: %d\n", elems);
printf("Number of different digits: %d\n", diff);
printf("Occurrence:\n");
for(n = 0; n < 10; n++) {
if(count[n]) {
printf(" %d of %d\n", count[n], n);
}
}
return 0;
}
Program session:
Enter a whole number: 82773712
Number of digits entered: 8
Number of different digits: 5
Occurrence:
1 of 1
2 of 2
1 of 3
3 of 7
1 of 8

C Program to list Armstrong Numbers upto 1000

#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int i , n , sum=0, rem;
clrscr();
for(i=1;i<=1000;i++)
{
while(i!=0)
{
rem = i%10;
sum = sum + pow(rem,3);
i = i / 10;
}
if(i == sum)
printf("\n %d", i);
}
getch();
}
I tried the above code for printing Armstrong Numbers upto 1000 . The output that I got was a list of zeros. I am not able to find the error in the code. Thanks in advance :)
You should keep a copy of i, so that it could be kept for comparison with the sum variable.
As of now, you compare sum and i, at every step when i has become 0.
You should use a temp variable to store value of i(before performing i/=10).
Also, you can't keep i in the while-loop as it would always be 0, and hence post increment will have no effect on it. You should need another temporary variable, say div.
And, you should finally print temp.
Also, an Armstrong number is an n-digit number that is equal to the sum of the nth powers of its digits.
So, for 1000, you need to caclculate the 4th power.
int temp,div;
for(i=1;i<=1000;i++)
{
temp = i;
div = i;
while(div!=0)
{
rem = div%10;
sum = sum + pow(rem,3);
div = div / 10;
}
if(temp == sum)
printf("\n %d", temp);
}
NOTE :- Probably you're using Turbo C compiler(check that header <conio.h>), which you shouldn't(you should avoid it). You should use GCC(on Linux system), CodeBlocks IDE(on Windows).
You can also use this code to print Armstrong number in given range.
#include<stdio.h>
int main()
{
int num,r,sum,temp;
int min,max;
printf("Enter the minimum range: ");
scanf("%d",&min);
printf("Enter the maximum range: ");
scanf("%d",&max);
printf("Armstrong numbers in given range are: ");
for(num=min;num<=max;num++)
{
temp=num;
sum = 0;
while(temp!=0)
{
r=temp%10;
temp=temp/10;
sum=sum+(r*r*r);
}
if(sum==num)
printf("%d ",num);
}
return 0;
}

Resources