C program to find the second largest element (also the largest) [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
This is the code I wrote and I'm wondering if there is any solution for the way I am thinking(the second number should be < largest and also bigger than the previous number). Thanks and sorry for [duplicate] but I am really curious if there is anything similar.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main()
{
int arr[10];
int i;
int greatest;
int second;
printf("Enter 10 values:");
for (i = 0; i < 10; i++)
{
scanf("\n%d", &arr[i]);
}
greatest = arr[0];
for (i = 1; i < 10; i++)
{
if (greatest < arr[i])
{
greatest = arr[i];
}
}
second = arr[i];
for (i = 0; i < 10; i++)
{
if (arr[i] < greatest && second > arr[i - 1])
{
second = arr[i];
}
}
printf("The greatest number is : %d", greatest);
printf("\nThe second greatest number is: %d", second);
return 0;
}

Your key mistake would be here:
for (i = 1; i < 10; i++)
{
if (greatest < arr[i])
{
greatest = arr[i];
}
}
second = arr[i];
Your loop conditions means that when the loops ends, i must be 10. That means arr[i] is out of bounds. This invokes undefined behavior. We have no way of knowing what the value of second is going into the next loop, and this will potentially affect your results.
You likely meant: second = arr[0] to initialize second with the first element in arr.
Having initialized second properly, you'd want to change that value only if the current element in the list is greater than the existing value for second and smaller than greatest.
In your code you've compared second to arr[i - 1]. When i is 0 on the first iteration, this will give you a negative index.
second = arr[0];
for (size_t i = 1; i < 10; i++) {
if (arr[i] < greatest && arr[i] > second) {
second = arr[i];
}
}
As a general suggestion, you do not need to declare your variables all at the beginning of the function in modern C. Declare them closer to actual use. Additionally, your i variables do not convey useful information beyond the scope of the loops, so scope them to the loops. That would have helped you catch the first out of bounds array access.

The solution
#include <limits.h>
#include <stdio.h>
int main()
{
int n = 5;
int arr[n] = {1, 2, 3, 4, 5};
int largest = INT_MIN, second = INT_MIN;
for(int i = 0; i < n; i++)
{
if(arr[i] > largest)
{
second = largest;
largest = arr[i];
}
else if(arr[i] > second && arr[i] != largest)
{
second = arr[i];
}
}
printf("Largest: %d\nSecond: %d\n", largest, second);
}
Okay so here is the trick
When iterating through the array you have three cases.
The first case is that you have found a number greater than the largest number you have kept.
We attempt to initially keep the largest number at a minimum, hence the INT_MIN, so that any initial number that the array has will be within our scope. If we assume the initial largest number to be 0 then negative values wouldn't be considered at all and the program would fail if the array consisted of all negative numbers (an array with only 1 positive number would also fail since we also want the second largest).
If a greater number than the largest value is detected, we assign the largest value as the detected value. Since the former largest number is now the second-largest value we assign second to be largest. Hence
second = largest;
largest = arr[i];
The second case is that we have encountered a number that is not greater than the largest number that we currently hold but is greater than the second. Then we assign second to the said value hence:
second = arr[i];
The third case is that we have encountered a value that is neither larger than the larger nor larger than the second. We ignore the number if that is the case.
What is wrong with your code
The part that deals with the greatest number looks correct. However, the way that you set second to be arr[i] is wrong since i would be 10 here and arr[i] would be out of the bounds of the array. Also, you are iterating from 0 to 10 and checking arr[i-1] which is clearly unsafe.

this should work.
if(arr[1] > arr[0]){
greatest = arr[1];
second = arr[0];
}else{
greatest = arr[0];
second = arr[1];
}
for(int i=2;i<10;i++)
{
if(second < arr[i]){
if(greatest < arr[i]){
second = greatest;
greatest = arr[i];
}
else{
second = arr[i];
}
}
}
First I fill greatest and second with the first two entries of the array in the correct order.
Then I run, in a for-loop, from the 3rd (as i already sorted the first 2) to the 10th value and check for each entry:
if the value is greater than second and also greater than
greatest then this value is now the greatest value. thus the current
greatest value is now the 2nd greatest value.
if the value is greater than second and smaller than greatest then
this value is the 2nd greatest value. and the greatest value remains.
if the value is smaller than second it is neither the greatest nor
the 2nd greatest value.

Related

C program to find each of the indices of the maximum element in an array (there are multiple elements with the same max value in different positions)

What I want: Suppose there is an array of some size. First, I want to find the maximum element in the array, and if there is more than one element with the same maximum value, then I want to store each of the indices of the maximum element without altering the ordering of the elements in the array.
Example: Let's say there are two classes: class A & class B. In an exam, each student of class A scored differently from the others, so we could easily find the maximum score and who scored it in the said exam. However, in the same exam, two students from class B scored the maximum score. Now, we have to identify those two students (with the help of their roll numbers, say) and the score they scored. I don't know how to do that!
What I know: I know how to code a C program to find the maximum value in an array with its index value. But, if there are multiple elements with the same max value in different positions in an array, then I think I would need a new array to store the indices of the max element. Once I achieve that, I could easily find the max value with the aid of any of the stored indices.
My attempt:
#include<stdio.h>
int main(void)
{
size_t arr[5] = {2,8,10,7,10};
size_t i,j,max = arr[0];
size_t indices[5]={0};
for(j = 0;j < 5; ++j)
{
for(i = 0;i < 5; ++i)
{
if(arr[i] >= max)
indices[j] = i;
}
printf("Max Value: %zu ----> Position: %zu\n",arr[indices[j]],indices[j]+1);
}
return 0;
}
The output it generates:
Max Value: 10 ----> Position: 5
Max Value: 10 ----> Position: 5
Max Value: 10 ----> Position: 5
Max Value: 10 ----> Position: 5
Max Value: 10 ----> Position: 5
(I knew that it won't work, and it didn't as well. The index 3 is getting lost in the process!)
The desired output should read something like this:
Max Value: 10 ----> Position: 3
Max Value: 10 ----> Position: 5
Please suggest how I can code a C program that can perform the desired task.
First thing, you are never overwritting max variable, so you are comparing each value on the array against arr[0], in this case 2.
Once fixed this you have multiple solutions for your problem.
Easiest one (though not the most efficient): iterate once to get the maximum value, and iterate again to get each occurence of that value.
Alternative: iterate only once. If arr[i] < max do nothing. If arr[i] == max store its index. If arr[i] > max update max, clear indices list and store current index.
Also, take care when storing indices, as 0 represents the first element of an array and should not be used as "empty" value.
Edit:
To clarify last sentence, keep in mind that in C, arrays are indexed from 0 to SIZE-1, instead of 1 to SIZE. Imagine that you make a variable to store an array index, let's call it index, and you initialize it like:
int index = 0;
Even though 0 is usually a neutral value, in this case means "the first element of the array". This doesn't necessarily mean that your code will break, but may lead to some tricky errors and poor clarity of the code.
Since indexes are always 0 or higher, using -1 as neutral value can be a good idea.
First loop to find the maximum element, then loop to find positions having value equal to that maximum.
#include<stdio.h>
int main(void)
{
size_t arr[5] = {2,8,10,7,10};
size_t max = arr[0];
size_t indices[5]={0};
for(size_t i = 0; i < 5; ++i) if(arr[i] > max) max = arr[i];
size_t top = 0; // top contains count of elements with val = max
for(size_t j = 0; j < 5; ++j)
{
if(arr[j]==max){
indices[top] = j;
printf("Max Value: %zu ----> Position: %zu\n",arr[indices[top]],indices[top]+1);
top++;
}
}
return 0;
}
The following code should produce the results you desire:
#include <stdio.h>
int main(){
int j, i, max, element, maxElement = 0;
int arr[5] = {2,8,10,7,10};
for(i = 0;i < 5; i++){ // loop to find highest index
element = arr[i];
if(element > max)max = element;} // highest index stored in 'max'
for(j = 0; j < 5; j++){ // second loop to find instances where 'max' is matched
maxElement = arr[j];
if(arr[j] == max)
printf("arr[%d] has max of %d\n",j,max);
}
return 0;
}
This creates the output:
arr[2] has max of 10
arr[4] has max of 10

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])));

checking if a array has numbers in it from 0 to length -1 in C

I have got an assignment and i'll be glad if you can help me with one question
in this assignment, i have a question that goes like this:
write a function that receives an array and it's length.
the purpose of the function is to check if the array has all numbers from 0 to length-1, if it does the function will return 1 or 0 otherwise.The function can go through the array only one.
you cant sort the array or use a counting array in the function
i wrote the function that calculate the sum and the product of the array's values and indexes
int All_Num_Check(int *arr, int n)
{
int i, index_sum = 0, arr_sum = 0, index_multi = 1, arr_multi = 1;
for (i = 0; i < n; i++)
{
if (i != 0)
index_multi *= i;
if (arr[i] != 0)
arr_multi *= arr[i];
index_sum += i;
arr_sum += arr[i];
}
if ((index_sum == arr_sum) && (index_multi == arr_multi))
return 1;
return 0;
}
i.e: length = 5, arr={0,3,4,2,1} - that's a proper array
length = 5 , arr={0,3,3,4,2} - that's not proper array
unfortunately, this function doesnt work properly in all different cases of number variations.
i.e: length = 5 , {1,2,2,2,3}
thank you your help.
Checking the sum and product is not enough, as your counter-example demonstrates.
A simple solution would be to just sort the array and then check that at every position i, a[i] == i.
Edit: The original question was edited such that sorting is also prohibited. Assuming all the numbers are positive, the following solution "marks" numbers in the required range by negating the corresponding index.
If any array cell already contains a marked number, it means we have a duplicate.
int All_Num_Check(int *arr, int n) {
int i, j;
for (i = 0; i < n; i++) {
j = abs(arr[i]);
if ((j >= n) || (arr[j] < 0)) return 0;
arr[j] = -arr[j];
}
return 1;
}
I thought for a while, and then i realized that it is a highly contrained problem.
Things that are not allowed:
Use of counting array.
Use of sorting.
Use of more than one pass to the original array.
Hence, i came up with this approach of using XOR operation to determine the results.
a ^ a = 0
a^b^c = a^c^b.
Try this:
int main(int argc, char const *argv[])
{
int arr[5], i, n , temp = 0;
for(i=0;i<n; i++){
if( i == 0){
temp = arr[i]^i;
}
else{
temp = temp^(i^arr[i]);
}
}
if(temp == 0){
return 1;
}
else{
return 0;
}
}
To satisfy the condition mentioned in the problem, every number has to occour excatly once.
Now, as the number lies in the range [0,.. n-1], the looping variable will also have the same possible range.
Variable temp , is originally set to 0.
Now, if all the numbers appear in this way, then each number will appear excatly twice.
And XORing the same number twice results in 0.
So, if in the end, when the whole array is traversed and a zero is obtained, this means that the array contains all the numbers excatly once.
Otherwise, multiple copies of a number is present, hence, this won't evaluate to 0.

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.

Counting occurrences of the largest number

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;
}

Resources