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])));
Related
I have to find all of the elements which have the maximum frequency. For example, if array a={1,2,3,1,2,4}, I have to print as 1, also 2. My code prints only 2. How to print the second one?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define n 6
int main(){
int a[n]={1,2,3,1,2,4};
int counter=0,mostFreq=-1,maxcnt=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]==a[j]){
counter++;
}
}
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
}
printf("The most frequent element is: %d",mostFreq);
}
How to print the second one?
The goal it not only to print a potential 2nd one, but all the all of the elements which have the maximum frequency.
OP already has code that determines the maximum frequency. Let us build on that. Save it as int target = mostFreq;.
Instead of printing mostFreq, a simple (still O(n*n)) approach would perform the same 2-nested for() loops again. Replace this 2nd:
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
With:
if(counter == target){
; // TBD code: print the a[i] and counter.
}
For large n, a more efficient approach would sort a[] (research qsort()). Then walk the sorted a[] twice, first time finding the maximum frequency and the 2nd time printing values that match this frequency.
This is O(n* log n) in time and O(n) in memory (if a copy of the original array needed to preserve the original). If also works well with negative values or if we change the type of a[] from int to long long, double, etc.
The standard student solution to such problems would be this:
Make a second array called frequency, of the same size as the maximum value occurring in your data.
Init this array to zero.
Each time you encounter a value in the data, use that value as an index to access the frequency array, then increment the corresponding frequency by 1. For example freq[value]++;.
When done, search through the frequency array for the largest number(s). Optionally, you could sort it.
We can (potentially) save some effort in an approach with unsorted data by creating an array of boolean flags to determine whether we need to count an element at all.
For the array {1, 2, 3, 1, 2, 4} we do have nested for loops, so O(n) complexity, but we can avoid the inner loop entirely for repeated numbers.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int arr[] = {1, 2, 3, 1, 2, 4};
size_t arr_size = sizeof(arr) / sizeof(*arr);
bool checked[arr_size];
for (size_t i = 0; i < arr_size; i++) checked[i] = false;
unsigned int counts[arr_size];
for (size_t i = 0; i < arr_size; i++) counts[i] = 0;
for (size_t i = 0; i < arr_size; i++) {
if (!checked[i]) {
checked[i] = true;
counts[i]++;
for (size_t j = i+1; j < arr_size; j++) {
if (arr[i] == arr[j]) {
checked[j] = true;
counts[i]++;
}
}
}
}
unsigned int max = 0;
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] > max) max = counts[i];
}
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] == max)
printf("%d\n", arr[i]);
}
return 0;
}
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.
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
I am making a program which finds the smallest number in the array without sorting it.. The output is always 0. Please explain me why?
#include<stdio.h>
#include<conio.h>
void main() {
int num[5] = {5, 2, 1, 6, 9}, i, j;
int min = num[0];
for (i=0; i<5; i++) {
if (min > num[i+1]) {
min = num[i+1];
}
}
printf("Smallest number is %d", min);
getch();
}
In this expression: num[i+1] you're trying to access an element outside of the array - valid array indexes go from zero to the array's length minus one (which is 4 in this case, but 4+1 is out of the array).
And anyway you should not hard-code array lengths, write your loop like this instead:
for (i = 1; i < num.length; i++) {
if (num[i] < min) {
min = num[i];
}
}
That way it'll always work, it won't matter the actual length of the array.
When i is 4 you are accessing num[5] which is outside the range of the array num. There are no guarantees what num[5] would be but most of the time there are couple trailing 0's after new memory allocation. It should be
for (i=1; i<5; i++) {
if (min > num[i]) {
min = num[i];
}
}
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;
}