Find the number that appears the most in an array - c

I have been debugging this problem for one night but still have no idea what has gone wrong. Let's say I input an array of 6 numbers which is {100,150,150,200,200,250} since 150 and 200 appear the same number of time then output the smaller number.
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[20] = { NULL }, num, result;
printf("Input a number(1-20) and enter a series of numbers in ascending order: \n");
scanf_s("%d", &num);
for (int k = 0; k < num; k++) {
scanf_s("%d", &arr[k]);
}
int c1, c2, i, j;
int temp = 0;
j = result = 0;
c1 = c2 = 1;
for (i = 1; i <= num-2; i++) { /*Add c1 if the value is the same*/
int a = arr[i];
if (arr[i+1] == a) c1++;
else {
j = i + 1;
temp = arr[j];
while (1) {
if (arr[j+1] == temp) {
c2++;
j++;
}
else break;
}
}
if (c2 > c1) { /*Move i to the position after j*/
c1 = 0;
result = temp;
}
if ((c2 < c1) || (c2 == c1)) { /*Move j to the next position*/
result = a;
c2 = 0;
}
i = j + 1;
}
printf("Number that appears the most time:%d\n", result);
return 0;
}
Will edit everytime after I did some progress
This is what I have done so far.
The output is correct for {100,150,150,200,200,250} but now the loop is stuck if I input a larger array with 8 numbers {100,100,100,150,150,200,250,300}. Help##

The error is in this part:
while (i <= num) { /*Add c1 if the value is the same*/
if (arr[i+1] == a)
Here i should be less than num-1, as you get numbers, the index goes from 0 to num-1, normally i<num would be ok, but you have done i+1 inside the loop so loop must only run from 0 to num-2.
Though, from your logic it should be arr[i] not arr[i+1]
And this part
int a = arr[i];
if (arr[i+1] == a) c1++;
Why would you assign a to value of arr[i] then again check with arr[i+1]? you only get c1 increasing with every duplicate value.
And this part at the end.
i=j+1
which is causing the infinite loop.
This would probably solve your problem although it is not a good solution:
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[20], num, result;
printf("Input a number(1-20) and enter a series of numbers in ascending order: \n");
scanf("%d", &num);
printf("Now enter the numbers");
for (int k = 0; k < num; k++) {
scanf("%d", &arr[k]);
}
int c1, c2, i, j;
int temp = 0;
j = 0;
result=arr[0];
c2 = 1;
for (i = 0; i < num; i++) { /*Add c1 if the value is the same*/
int a = arr[i];
c1=1;
for(j=i+1;j<num;j++)
{
if (arr[i]==arr[j])
{
c1+=1;
}
}
if(c1>c2)
{
c2=c1;
result=arr[i];
}
else if(c1==c2 && result>arr[i])
{
result=arr[i];
}
}
printf("Number that appears the most time:%d\n", result);
return 0;
}
Other than that, it has a better approach for your problem. make a struct of {int key, int count} then use it to store counts of all unique members in your array, then extract what you need.
Here is the code to what i was saying about, it might be hard to look into if you don't know about pointers & dynamic memory yet. but you'll get the logic.
#include<stdio.h>
#include<stdlib.h>
int main()
{
struct counts
{
int key;
int count;
};
int * data;
int num;
printf("Enter the number of data:");
scanf("%d",&num);
data=malloc(num*sizeof(int));
int i,j;
printf("Enter the data in order:");
for (i=0;i<num;i++)
{
scanf("%d",data+i);
}
struct counts *table;
int table_len=1;
int flag;
table=malloc(sizeof(struct counts));
table[0].key=data[0];
table[0].count=1;
for (i=1;i<num;i++)
{
flag=0;
for(j=0;j<table_len;j++)
{
if (table[j].key==data[i])
{
flag=1;
table[j].count+=1;
break;
}
}
if (flag==0)
{
table=realloc(table,++table_len* sizeof(struct counts));
table[table_len-1].key=data[i];
table[table_len-1].count=1;
}
}
//if you want to see at the table
printf("data\t\tcount\n");
for(i=0;i<table_len;i++)
{
printf(" %d\t\t%d\n",table[i].key,table[i].count);
}
//now to extract the value
int answer,count;
answer=table[0].key;
count=table[0].count;
for(i=1;i<table_len;i++)
{
if(count>table[i].count)
{
continue;
}
else if(count<table[i].count)
{
answer=table[i].key;
count=table[i].count;
}
else if(answer>table[i].key)
{
answer=table[i].key;
}
}
printf("The number with highest frequency is: %d\n",answer);
return 0;
}

Related

Can't get the desired output of this binary search program in c language

We are required to make two functions, 1] Bubble Sort and 2] Binary Search. If an element doesn't belong to the array, the 2]nd function should return -1. In the main function we get the input and if the element does not lie in the array, we should print "Element not found". I have written the program according to the specifics that were asked in the question.
The 1]st function, Bubble Sort is working fine but 2]nd function is only giving "Element not found" as the output, no matter what the value. Please suggest a solution.
void bubbleSortDec(int arr[10])
{
int i=0,j=0,temp=0;
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(arr[j]<arr[j+1])
{
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
int binarySearch(int arr[10], int x)
{
bubbleSortDec(arr);
int first, last=0, middle=0;
first = 0;
last = 10 - 1;
middle = (first+last)/2;
while (first <= last) {
if (arr[middle] < x)
first = middle + 1;
else if (arr[middle] == x) {
printf("%d found at location %d.\n", x, middle+1);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if (first > last)
{
return -1;
}
}
int main()
{
int arr[10];
int i, x,k=0;
printf("Enter 10 numbers \n");
for(i=0; i<10;i++)
{
scanf("%d", &arr[i]);
}
printf("Enter a number to be searched \n");
scanf("%d", &x);
k=binarySearch(arr,x);
if(k==-1)
printf("Element not found \n");
}
Your bubble sort sorts the array in decreasing order. That is not a problem of course, you can still use in that way but you need to change your binary search. The problem is here.
Let's assume you have an array that is sorted in decreasing order and let's say you are searching for 17.
65 54 32 17 9
Than you are looking for the midde element that is 32. In your code if the element that you are looking for is smaller than the middle element, you continue the search with the lower part of the array. But in this case it is wrong. Because the elements that are on the lower part of the array are bigger than the middle element. You need to look for the upper side of the array.
So you have two option.
First you can change your bubble sort to sort the array in increasing order.
void bubbleSortDec(int arr[10])
{
int i=0,j=0,temp=0;
for(i=0;i<9;i++)
{
for(j=0;j<9-i;j++)
{
if(arr[j]>arr[j+1]) // Change is here. (this "<" to this ">")
{
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
Or you can change your binary search to this.
int binarySearch(int arr[10], int x)
{
bubbleSortDec(arr);
int first, last=0, middle=0;
first = 0;
last = 10 - 1;
middle = (first+last)/2;
while (first <= last) {
if (arr[middle] > x) // Change is here. (this "<" to this ">")
first = middle + 1;
else if (arr[middle] == x) {
printf("%d found at location %d.\n", x, middle+1);
/*
Returning anything except "-1" is okey. Because you only check for "-1".
*/
return middle;
}
else
last = middle - 1;
middle = (first + last)/2;
}
/*
If you couldn't find the element in while loop that
means the element is not in the array. You don't need to check it again.
*/
return -1;
}
And lastly I wrote the same code in this way.
#include <stdio.h>
#define SIZE 10
void swap(int *i1, int *i2) {
int temp = *i1;
*i1 = *i2;
*i2 = temp;
}
void bubbleSort(int arr[SIZE]) {
int i, j;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE - i - 1; j++) {
if (arr[j] > arr[j + 1]) swap(arr + j, arr + j + 1);
}
}
return;
}
int binarySearch(int arr[SIZE], int x) {
int first = 0, last = SIZE - 1;
while (first <= last) {
int middle = (first + last) / 2;
if (arr[middle] == x) {
return middle;
} else if (x < arr[middle]) {
last = middle - 1;
} else {
first = middle + 1;
}
}
return -1;
}
int main() {
int arr[SIZE];
printf("Enter %d numbers \n", SIZE);
int i; for(i = 0; i < SIZE; i++) scanf("%d", arr + i);
printf("Enter a number to be searched \n");
int x;
scanf("%d", &x);
bubbleSort(arr);
int k = binarySearch(arr, x);
if (k == -1) printf("Element not found!\n");
else printf("Element found at index %d.\n", k + 1);
return 0;
}

How to fix C2109:subscript requires array or pointer type

I'm having problem with some homework here. I'm totally newbie in programming, so anything should be helpful. I don't know how to fix C2109 error in C.
As you see, I have a float array that I have to sort, and look for the number 55.5
#include <stdio.h>
#include <conio.h>
#include <math.h>
main() {
float mr1[30], pom = 0;
int i, indeks = -1, j, n, start, end, mid;
printf("Enter length of array n<=30:\n");
scanf("%d", &n);
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
scanf("%f", &mr1[i]);
}
for (i = 0; i <n - 1; i++) {
for (j = i + 1; j < n; j++)
if (mr1[i] > mr1[j]) {
mr1[i] = pom;
mr1[i] = mr1[j];
mr1[j] = mr1[i];
}
}
start = 0;
end = n - 1;
do {
mid = (start + end) / 2
if (mr1[mid] == 55.5) {
indeks = mid;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
kraj = mid - 1;
}
}
} while (poc <= kraj && indeks < 0);
printf("Number 55.5 is on indeks:\n");
printf("%d", indeks);
}
There are multiple issues in the code:
The swapping code is incorrect. It should read:
pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
you did not translate all poc as start and kraj as end.
There is a missing ; after mid=(start+end)/2
main() is an obsolete prototype for the main function, you should specify the return type int.
the do / while loop will not handle an empty array correctly. You should use a while loop instead. As a rule of thumb, do / while loop are very often incorrect, sometimes in subtile ways.
Here is a corrected version:
#include <stdio.h>
int main() {
float mr1[30];
int n, i, j, index, start, end, mid;
printf("Enter length of array n<=30:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 30) {
printf("invalid length\n");
return 1;
}
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
if (scanf("%f", &mr1[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
/* sort the array with simplistic swap sort */
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (mr1[i] > mr1[j]) {
/* swap entries */
float pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
}
}
}
/* try and locate 55.5 with binary search */
index = -1;
start = 0;
end = n - 1;
while (start <= end) {
mid = (start + end) / 2;
if (mr1[mid] == 55.5) {
index = mid;
break;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
end = mid - 1;
}
}
}
if (index >= 0) {
printf("Number 55.5 is at index %d\n", index);
} else {
printf("Number 55.5 is not present\n");
}
return 0;
}
Note also that 55.5 happens to have an exact representation as a float, but comparing floating point values with == may yield surprising results when the approximate value is not exactly identical to the expected value.

Why is the strong number being displayed once in the code?

The code is not printing all the strong numbers in the given range of lower limit and upper limit. It is only printing 1. Cannot find either logical or syntax error. Please help.
New to C programming. Was practicing C questions online. The question was about to print all the strong numbers.
int strong (int lower_limit,int upper_limit)
{
int i,temp1,temp2,product=1,sum=0;
for(i=lower_limit;i<=upper_limit;i++)
{
temp1=i;
while(temp1!=0)
{
temp2=temp1%10;
for( ;temp2>0;temp2--)
{
product=temp2*product;
}
temp1/=10;
sum=sum+product;
}
if(i==sum)
printf("%d is a strong number\n",i);
}
return 0;
}
int main()
{
int lower_limit,upper_limit;
printf("Enter lower limit number\n");
scanf("%d",&lower_limit);
printf("Enter upper limit number\n");
scanf("%d",&upper_limit);
strong(lower_limit,upper_limit);
return 0;
}
If I put lower_limit as 1 and upper_limit as 1000 I am supposed to get 1,2,and 145.
The sum and product are never reset. To avoid such cases, it's better to declare the variable where is really needed. Otherwise you end up with temporary states if you forget to reset/update the values
This should work:
int strong(int lower_limit, int upper_limit) {
int i, temp1, temp2, product = 1, sum = 0;
for (i = lower_limit; i <= upper_limit; i++) {
temp1 = i;
sum = 0; // should be reset when iterating through interval
while (temp1 != 0) {
temp2 = temp1 % 10;
product = 1; // should reset for each digit
for (; temp2 > 0; temp2--) {
product = temp2 * product;
}
temp1 /= 10;
sum = sum + product;
}
if (i == sum)
printf("%d is a strong number\n", i);
}
return 0;
}
int i ,rem ,num , fact=1, result=0;
int tempnum = num;
while(tempnum != 0)
{
rem = tempnum % 10; // gives the remainder
for(i=1;i<=rem;i++)
{
fact = fact * i;
}
result += fact;
fact = 1; //to repeat the loop keeping fact as 1 because the value will change after every loop
tempnum /= 10 ;
}

How to print All zeros in C?

I want to print all the zeros in the input using this code.
for example:
input: 10000 -------------- output: 0000
but I get this:
input: 10000 -------------- output: 0
this is the source code in C99:
#include<stdio.h>
int main() {
int co = 0, inputNumber, i, j, prod = 1, number = 0, ten = 10, newValue;
int numberOfInputs;
scanf("%d", &numberOfInputs);
for(i = 1; i <= numberOfInputs; i++) {
scanf("%d", &inputNumber);
for(j = 1; j < inputNumber; j++) {
if(inputNumber % j == 0) {
prod = prod * j;
}
}
if(prod < 10000)
printf("%d", prod);
else {
newValue = prod;
while((int)prod / 10 != 0) {
prod = (int) prod/10;
co++;
number = newValue % ten;
ten *= 10;
if(co == 4) {
printf("%d \n", number);
break;
}
}
}
}
return 0;
}
Please some help guys :)
So basically, you want to print out the four lowest-order digits of the product with leading zeros, which is pretty simple:
printf( "%04d\n", prod % 10000 );
Cleaning up and reformatting your code a bit basically reduces to this:
#include <stdio.h>
int main( void )
{
int inputNumber, i, j, prod=1;
int numberOfInputs;
scanf( "%d", &numberOfInputs );
for(i = 1; i <= numberOfInputs; i++ )
{
scanf("%d", &inputNumber);
for(j = 1; j < inputNumber; j++ )
{
if( inputNumber % j == 0)
{
prod = prod*j;
}
}
printf( "%04d\n", prod % 10000 );
}
return 0;
}
Using a completely different approach, you can do this:
#include<stdio.h>
int main(){
int zeroCounter=0;
char inputNumber[256];
printf("Please enter the numerical value:");
fgets(inputNumber,256, stdin);
int j;
for(j=0; inputNumber[j]!='\n'; j++)
{
if(inputNumber[j]=='0') zeroCounter++;
}
printf("this value had %d zeros, here they are: ",zeroCounter);
while(zeroCounter!=0)
{
printf("0");
zeroCounter--;
}
printf("\n");
return 0;
}
what this code does is it sniffs the character array you input, and counts the 0 characters. then it can print them if required. no division and bitshifting shenanigans required.
Well your current problems are that because of the overflows, prod ends to be 0. And as 0 < 10000 you just pass through the single print: if(prod<10000)printf("%d",prod); just bypassing all your complex printing code.
In fact it overflows (to a negative value) at least at for a value as small as 84.
But that's not all. Even if prod does not overflow, you compute a number of at most 4 digits in number but print if in %d format. If number is less than 1000, you will not print the highest order 0 with that format, but you should use %04d.
Here is a minimally fixed version:
int main(){
int co=0,inputNumber,i,j,prod=1,number=0,ten=10,newValue;
int numberOfInputs;
scanf("%d",&numberOfInputs);
for(i=1;i<=numberOfInputs;i++)
{
scanf("%d",&inputNumber);
prod = 1; /* reset prod */
for(j=1;j<inputNumber;j++) {
if(inputNumber%j==0) {
prod = prod*j;
if (prod <= 0) {
break;
}
}
}
if (prod <=0) {
printf("Overflow\n");
}
else if(prod<10000) {
printf("%04d\n",prod);
}
else
{
newValue = prod;
while((int)prod/10 != 0)
{
prod = (int)prod/10;
co++;
number = newValue%ten;
ten*=10;
if(co==4)
{
printf("%04d \n",number);
break;
}
}
}
}
return 0;
}
But in fact the else part should just be:
else
{
printf("%04d \n",prod % 10000);
}

Largest palindrome made from the product of two 3-digit numbers with C

The code is trying to find the largest palindrome made from the product of two 2-digit numbers. The answer is 91*99 = 9009 but I keep getting 990, which is not even a palindrome. I really appreciate the help!
#include <stdio.h>
int main()
{
int i = 10;
int j = 10;
int a = 0;
int b = 0;
int array[100] = {0};
int divider = 10;
int num;
int great;
int product;
int n;
int flag;
/*Loop through first 2 digit number and second 2 digit number*/
while (i<100)
{
while (j < 100)
{
product = i*j;
array [a] = product % 10;
n = product / divider;
while (n != 0)
{
a++;
num = n%10;
divider *=10;
array[a]=num;
n = product/divider;
}
flag = 0;
while (b<a)
{
if (array[b] != array[a])
{
flag = 1;
}
b++;
a--;
}
if (flag == 0)
{
great = product;
}
j++;
a = 0;
b = 0;
}
i++;
}
printf("The largest palindrome is %d \n", great);
return 0;
}
Here is a code snippet you can try.
#include <stdio.h>
void main()
{
int a = 1; // first integer
int b = 1; // second integer
int currentNumber;
int currentPalin; if a palindrome is found, its stored here
while (a<100){ //loop through the first number
while (b<100){ // loop through the second number
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){ //check for palindrome
currentPalin = currentNumber;
}
b = b+1; //increment the second number
}
b = a; // you could have set b=1 but it would not be an efficient algorithm because
//some of the multiplication would occur twice. eg- (54*60) and (60*54)
a = a +1; //increment the first number
}
printf ("Largest palindrom is %d \n", currentPalin);
getchar();
}
// method for finding out reverse
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
// when you divide a number by 10, the
//remainder gives you the last digit. so you are reconstructing the
//digit from the last
n = n/10;
}
return reverse;
}
Update:- As suggested by M Oehm, I have modified the code to make it more general.
#include <stdio.h>
void main()
{
int a = 1;
int b = 1;
int currentNumber;
int currentPalin=0;
while (a<100){
while (b<100){
currentNumber = a*b;
if (currentNumber == reverse(currentNumber) ){
if (currentNumber>currentPalin){
currentPalin = currentNumber;
}
}
b = b+1;
}
b = 1;
a = a +1;
}
if (currentPalin==0){
printf("No Palindrome exits in this range");
}
else {
printf ("Largest palindrome is %d \n", currentPalin);
}
getchar();
}
int reverse(int n){
int reverse = 0;
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
return reverse;
}
An alternative approach to solve the problem.
#include<stdio.h>
int reverse(int num)
{
int result = 0;
while( num > 0)
{
result = result * 10 + (num%10);
num/=10;
}
return result;
}
int main()
{
int last_best = 1;
int best_i=1;
int best_j = 1;
const int max_value = 99;
for( int i = max_value ; i > 0 ; --i)
{
for(int j = i ; j > 0 ; --j){
int a = i * j;
if( last_best > a )
break;
else if ( a == reverse(a) )
{
last_best = a;
best_i = i;
best_j = j;
}
}
}
printf("%d and %d = %d\n", best_i,best_j,last_best);
}
And it is quite simple to follow.
It seems that you do not reinitialize variables at the beginning of loop. They keeps values from previous iterations. For example, j and divider. Put
j = 10;
before starting "j" loop, i.e.:
j = 10;
while (j < 100) ...
The same for divider:
...
j = 10;
while (j < 100) {
divider = 10;
...
If you were using for loops you would avoid this problem naturally:
for(i=10; i<100; i++) {
for(j=10; j<100; j++) {
...
}
}

Resources