Counting occurrences of the largest number - c

I have been attempting to code for a program that stores input into an array and then allows me to print it out. It also lets me know which number is the largest. What I am trying to figure out is how can I get my program to tell me the amount of times (occurrences) the largest number in array is input. Here is my code so far. As of now, this code outputs the numbers I enter to the array, the largest element in the array, and the occurrence of every number I input( The occurrences of the numbers are incorrect). In all the the amount of occurrences for every number turns out to be 0. Which is obviously incorrect. Again, I need my program to display the largest number (which it does) and the occurrences of ONLY the largest number. All advice, tips, or thoughts are welcome. Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int main()
{
int arrayNum[15];
int a;
int max=0;
int location;
for( a=0; a < 15; a++)
{
printf("Enter element %d:", a);
scanf("%d",&arrayNum[a]);
}
for(a=0; a < 15; a++)
{
printf("%d\n", arrayNum[a]);
}
for (a = 1; a < 15; a++)
{
if (arrayNum[a] > max)
{
max = arrayNum[a];
location = a+1;
}
}
printf("Max element in the array in the location %d and its value %d\n", location, max);
for(a=0; a<15; a++)
{
if(arrayNum[a+1] == arrayNum[a])
continue;
else
printf("Number %d: %d occurences\n", arrayNum[a]);
}
return 0;
}

I spot some problems in your code. First, the third for loop starts at 1, but it does not update the max as the value of arrayNum[0].
Then, for the problem at hand, I would have two variables:
int max; // The maximum value
int max_count; // The count of the maximum value
Then, the logic to find the greatest, and the count, is the following:
For each element, compare it with the maximum seen. If it is equal, increment max_count. If it is bigger, update max with the value, and set the max_count to 1. If it is smaller, ignore it. Something like:
max = arrayNum[0];
max_count = 1;
for (int a = 1; a < 15; ++a)
{
if (arrayNum[a] == max)
max_count++;
else if (arrayNum[a] > max)
{
max_count = 1;
max = arrayNum[a];
}
}

All you need to do is introduce a new variable to keep track of the number of occurrences of max. When a new value of max is found, set that count to zero. When a subsequent value is found equal to the max, increment the counter.
Incidentally, your code doesn't properly find the maximum in its current form. Try one test case where your array elements are all negative. Try another test case in which all the values are positive, and the first value entered (arrayNum[0]) is the maximum. You will find, in both cases, that your function will not actually find the maximum.

Just before you begin the below loop max is still 0 make
max = a[0];
for (a = 1; a < 15; a++)
{
if (arrayNum[a] > max)
{
max = arrayNum[a];
location = a+1;
}
}
Later
int n=0;
for(i=0;i<15;i++)
{
if(max == a[i])
n++;
}
printf("Number of times max appears in the array is %d\n",n);

Replace last for loop with below code
NoOfOccurances = 0;
for(a=0; a<15; a++)
{
if(max == arrayNum[a])
{
NoOfOccurances++;
}
}
printf("Number %d: %d occurences\n", max,NoOfOccurances);

For your third for-loop, the one where you find out the largest number in your array, I would suggest to set max to arrayNum[0], that way it will work even with negative numbers.
Then, to know how many occurrence of the highest number there is, you need a count variable that you increment (count++) each time a number of the array is equal to max. To do that you need another for-loop.
Good luck.

You can do what you want in just one loop iteration:
int count = 1;
int position = 0;
int max = arrayNum[0];
int N = 15;
int p;
for (p = 1; p < N; ++p)
{
if (arrayNum[p] > max) // Find a bigger number
{
max = arrayNum[p];
pos = p;
count = 1;
}
else if ( arrayNum[p] == max) // Another occurrences of the same number
count++;
}

A simple solution with time complexity of O(n)
int maxoccurence(int a[],int ar_size)
{
int max=a[0],count=0,i;
for(i=0;i<ar_size;i++)
{
if(a[i]==max)//counting the occurrence of maximum element
count++;
if(a[i]>max)//finding maximum number
{
max=a[i];
count=1;
}
}
printf("Maximum element in the array is %d\n",max);
return count;
}

Related

Finding the maximum integer of three integers in C

I just started learning how to code in C.
I tried creating a program that finds the maximum of three integers using arrays, but I don't really understand why does it work.
Can anybody more experienced help explain to me; why do I need to let max = 0 in order for the program to function?
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
int size, max;
int arr[3];
for (int i = 0; i < 3; i++) {
printf("Please enter your integer:\n");
scanf("%d", &arr[i]);
}
max = 0;
for (int i = 0; arr[i] >= max; i++) {
max = arr[i];
}
printf("This is the max number: %d", max);
return 0;
}
Thanks for the help everyone.
The proper loop would be:
int max= INT_MIN;
for (int i = 0; i<3; i++)
if (arr[i]> max) max= arr[i];
First of all, your code won't find the right answer in all test cases, and that's because of how you wrote your second for loop. For example if you have an input like 3, 2, 4, after the first for iteration you'll have max = 3 and the for loop will stop because the next element (2) is less than the current max (3). But the max value of this array is 4, not 3. You should change the second for loop like this:
for (int i=0;i<3;i++) {
(if array[i]>max) max = array[i];
}
Also, take note that you can initialize max to 0 only if you don't have negative numbers in the array, otherwise you might have incorrect results. So, if you can't make assumptions about your input values I would suggest you to simply initialize max with the first element of the array and do a loop starting from the second one to the end (for(i=1;i<3;i++).
A variable must be initialized before it can be used. The first use of max is:
for (int i = 0; arr[i] >= max; i++) {
... ^^^^^^^^^^^^^
}
The boundary condition in a for loop (i.e. arr[i] >= max) is evaluated before every iteration of the loop. A value for max is therefore required before the body of the loop is ever executed.
Thus, you must assign some value to max outside the loop, and, as you discovered, max = 0 is a suitable initial value for some inputs.
However as mentioned by Paul in the comments, this is not a suitable boundary condition for the result you’re trying to achieve. You should instead iterate over the entire array, setting the max value only if each array element is greater than the existing max value:
max = 0;
for (int i = 0; i < 3; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
If it's just for three:
#define MAX_SIMPLE(a, b) (((a) > (b)) ?(a) :(b))
int a[3] = {3, 2, 1};
printf("max is: %d\n", MAX_SIMPLE(a[0], MAX_SIMPLE(a[1], a[2])));

C program to find integer closest to 10

I am writing a program that will take any number of integers. The program will end when the terminal 0 has been entered. It will then output the number closest to 10 (except for the terminal character). If there are several numbers closest to 10 then it should output the last number entered.
My current code does read the numbers from the input stream, but I don't know how to implement the logic so that the program will give me the number that is closest to 10.
I know, that I need to keep track of the minimum somehow in order to update the final result.
#include <stdio.h>
int main() {
int n = 1;
int number = 1;
int numberArray[n];
int resultArray[n];
int min;
int absMin;
int result;
int finalResult;
while (number != 0) {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
for (int i = 0; i < n; i++) {
min = 10 - numberArray[i];
if (min < 0) {
absMin = -min;
}
else {
absMin = min;
}
resultArray[i] = absMin;
result = resultArray[0];
if (resultArray[i] < result) {
finalResult = resultArray[i];
}
}
printf("%d\n", finalResult);
return 0;
}
here's a simple code I wrote
One thing I must say is you can't simply declare an array with unknown size and that's what you have done. Even if the no. of elements can vary, you either take input the number of elements from the user OR (like below) create an array of 100 elements or something else according to your need.
#include <stdio.h>
#define _CRT_NO_WARNINGS
int main() {
int n = 0;
int number = 1;
int numberArray[100];
int resultArray[100];
int minNumber;
int *min;
do {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
while (number != 0);
resultArray[0] = 0;
min = &resultArray[0];
minNumber = numberArray[0];
for (int i = 0; i < n-1; i++) {
if(numberArray[i]>=10){
resultArray[i] = numberArray[i] - 10;
}
if(numberArray[i]<10){
resultArray[i] = 10 - numberArray[i];
}
if(resultArray[i] <= *min){
min = &resultArray[i];
minNumber = numberArray[i];
}
}
printf("\n%d",minNumber);
return 0;
}
I have improved your script and fixed a few issues:
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main()
{
int n;
int number;
int numberArray[n];
while (scanf("%d", &number) && number != 0) {
numberArray[n++] = number;
}
int currentNumber;
int distance;
int result;
int resultIndex;
int min = INT_MAX; // +2147483647
for (int i = 0; i < n; i++) {
currentNumber = numberArray[i];
distance = fabs(10 - currentNumber);
printf("i: %d, number: %d, distance: %d\n", i, currentNumber, distance);
// the operator: '<=' will make sure that it will update even if we already have 10 as result
if (distance <= min) {
min = distance;
result = currentNumber;
resultIndex = i;
}
}
printf("The number that is closest to 10 is: %d. It is the digit nr: %d digit read from the input stream.\n", result, resultIndex + 1);
return 0;
}
Reading from the input stream:
We can use scanf inside the while loop to make it more compact. Also, it will loop one time fewer because we don't start with number = 1 which is just a placeholder - this is not the input - we don't want to loop over that step.
I used the shorthand notation n++ it is the post-increment-operator. The operator will increase the variable by one, once the statement is executed (numberArray entry will be set to number, n will be increased afterwards). It does the same, in this context, as writing n++ on a new line.
Variables:
We don't need that many. The interesting numbers are the result and the current minimum. Of course, we need an array with the inputs as well. That is pretty much all we need - the rest are just helper variables.
Iteration over the input stream:
To get the result, we can calculate the absolute distance from 10 for each entry. We then check if the distance is less than the current minimum. If it is smaller (closer to 10), then we will update the minimum, the distance will be the new minimum and I have added the resultIndex as well (to see which input is the best). The operator <= will make sure to pick the latter one if we have more than one number that has the same distance.
I have started with the minimum at the upper bound of the integer range. So this is the furthest the number can be away from the result (we only look at the absolute number value anyway so signed number don't matter).
That's pretty much it.

How can I reduce the runtime?

Here is a link to the problem I'm trying to solve: http://acm.timus.ru/problem.aspx?space=1&num=1086
Here is my approach:
#include <stdio.h>
#include <math.h>
int main()
{
int n, i, m, p;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &m);
p = find_prime(m);
printf("%d\n", p);
}
return 0;
}
int find_prime(int a)
{
int i, p = 1, t, prime[15000], j;
prime[0] = 2;
for(i = 0; i < a; )
{
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
t = 0;
for(j = 0; prime[j] <= sqrt(p); j++)
{
if(p%prime[j] == 0 && p != 2)
{
t = 1;
break;
}
}
if(t != 1)
{
i++;
prime[i] = p;
}
}
return p;
}
I know the algorithm is fine and it produces the correct answer. But I always get "Time Limit Exceeded". I can't get the runtime download to 2 seconds. It's always equal to 2.031 seconds. I have tried few other approaches, for example, I iterated through all the numbers until I found the mth prime number, I tried skipping the even integers greater than 2 but I still get 2.031 seconds.
What should I do?
Your buffer for prime numbers doesn't need to be a local variable that's recalculated every time.
You can try to memoize by storing the buffer in the global scope and using a global counter to keep track of how many primes you have already calculated until now and which number was the maximum number requested.
If the next number that's requested from you is smaller than the previous maximum, you should fall back to the corresponding pre-calculated number. If the next number is larger than the previous maximum, make it the new maximum - and also try to start calculating from where you last left off.
Remove
if(p == 2)
{
p++;
}else
{
p = p + 1;
}
and replace it with
p++
as I understand it,
the problem is to find the next prime greater that the sum of all the prior input numbers.
That means there are certain expectations.
1) the sum of the prior input numbers is available in find_prime().
2) for simplification, the last found prime number is available in find_prime().
Neither of these expectations are implemented.
Then there is that 60 thousand byte array on the stack in find_prime().
Suggest moving that to a file global position and including a 'static' modifier.
move the prior sum of inputs to a file global location, so it is always available.
for overall speed,
calculate all the primes in the array as a first thing, thereby filling the array with prime values. then
1) add new input to sum,
2) index into array using sum.
3) return value found in array.

How to find the number of elements in the array that are bigger than all elements after it?

I have a function that takes a one-dimensional array of N positive integers and returns the number of elements that are larger than all the next. The problem is exist a function to do it that in a better time? My code is the following:
int count(int *p, int n) {
int i, j;
int countNo = 0;
int flag = 0;
for(i = 0; i < n; i++) {
flag = 1;
for(j = i + 1; j < n; j++) {
if(p[i] <= p[j]) {
flag = 0;
break;
}
}
if(flag) {
countNo++;
}
}
return countNo;
}
My solution is O(n^2). Can it be done better?
You can solve this problem in linear time(O(n) time). Note that the last number in the array will always be a valid number that fits the problem definition. So the function will always output a value that will be greater than equal to 1.
For any other number in the array to be a valid number it must be greater than or equal to the greatest number that is after that number in the array.
So iterate over the array from right to left keeping track of the greatest number found till now and increment the counter if current number is greater than or equal to the greatest found till now.
Working code
int count2(int *p, int n) {
int max = -1000; //this variable represents negative infinity.
int cnt = 0;
int i;
for(i = n-1; i >=0; i--) {
if(p[i] >= max){
cnt++;
}
if(p[i] > max){
max = p[i];
}
}
return cnt;
}
Time complexity : O(n)
Space complexity : O(1)
It can be done in O(n).
int count(int *p, int n) {
int i, currentMax;
int countNo = 0;
currentMax = p[n-1];
for(i = n-1; i >= 0; i--) {
if(currentMax < p[i])
{
countNo ++;
currentMax = p[i];
}
}
return countNo;
}
Create an auxillary array aux:
aux[i] = max{arr[i+1], ... ,arr[n-1] }
It can be done in linear time by scanning the array from right to left.
Now, you only need the number of elements such that arr[i] > aux[i]
This is done in O(n).
Walk backwards trough the array, and keep track of the current maximum. Whenever you find a new maximum, that element is larger than the elements following.
Yes, it can be done in O(N) time. I'll give you an approach on how to go about it. If I understand your question correctly, you want the number of elements that are larger than all the elements that come next in the array provided the order is maintained.
So:
Let len = length of array x
{...,x[i],x[i+1]...x[len-1]}
We want the count of all elements x[i] such that x[i]> x[i+1]
and so on till x[len-1]
Start traversing the array from the end i.e. at i = len -1 and keep track of the largest element that you've encountered.
It could be something like this:
max = x[len-1] //A sentinel max
//Start a loop from i = len-1 to i = 0;
if(x[i] > max)
max = x[i] //Update max as you encounter elements
//Now consider a situation when we are in the middle of the array at some i = j
{...,x[j],....x[len-1]}
//Right now we have a value of max which is the largest of elements from i=j+1 to len-1
So when you encounter an x[j] that is larger than max, you've essentially found an element that's larger than all the elements next. You could just have a counter and increment it when that happens.
Pseudocode to show the flow of algorithm:
counter = 0
i = length of array x - 1
max = x[i]
i = i-1
while(i>=0){
if(x[i] > max){
max = x[i] //update max
counter++ //update counter
}
i--
}
So ultimately counter will have the number of elements you require.
Hope I was able to explain you how to go about this. Coding this should be a fun exercise as a starting point.

issue with a sort method (C)

I'm having issues with a sort method I wrote. It is supposed to find the max value, and replace the last value in the array with the max (and move that value to where the last value was).
I've ran gdb, and it looks like the if statement always executes, and for some reason max = values[0] always sets max to 0. Granted I am very new to C so I might be wrong about what is going on.
/**
* Sorts array of n values.
*/
void sort(int values[], int n)
{
// TODO: implement an O(n^2) sorting algorithm
int max; //hold the max value through the iteration
int replaced; //to hold the value at the end of the array
int replacedhash; //to hold the location of the max value
do
{
replaced = values[n];
max = values[0]; //reset max to 0 for new iteration
for(int i = 0; i<n ; i++)
{
//check if the next value is larger,
//then update max and replacedhash if it is
if (max < values[i])
{
max = values[i];
replacedhash = i;
}
}
values[replacedhash] = replaced; //next three lines swap the values
n--;
values[n] = max;
} while (n!=0);
}
And I would use this by running:
int main() {
int test[] = {3,5,2,5,6,100,4,46};
sort(test, 8);
printarray(test, 8);
}
Error 1: replaced = values[n-1];
Your example in the problem statement is:
int test[] = {3,5,2,5,6,100,4,46};
sort(test, 8);
So you'll then look at test[8], which is undefined behavior
Error 2: replacedhash
replacedhash will be uninitialized if the first element of the array is the max. And it will probably have an incorrect value on later loops when the first element is the max.
My thoughts:
It appears to me that you've overcomplicating the code. You probably should just find the index in the array that has the maximum value, and then do the swap. It'll be simpler.
void sort(int values[], int n) {
do {
// Find index of maximum value
int max = 0;
for(int i=0; i<n; i++)
if (values[max] < values[i])
max = i;
// Swap
int temp = values[max];
values[max] = values[n-1];
values[n-1] = temp;
n--;
} while (n != 0);
}

Resources