Reputation: 861
I am really frustrated , I tried all day to make it works but never figured it out.
I need to find 2 largest
and 2 smalllest
numbers from arr[11]
.
Here is what I have been done so far :
int main(){
float arr[11] ,max = 0, max2, min, min2;
int i = 0;
for (i = 0; i < 11; i++){
scanf("%f", &arr[i]);
}
max = arr[0];
max2 = arr[0];
min = arr[0];
min2 = arr[0];
for (i = 1; i < 11; i++){
if (arr[i] > max)
max = arr[i];
if (arr[i] < min)
min = arr[i];
}
while (min == min2){
min2 = arr[1 + i];
i++;
}
for (i = 10; i > 0; i--){
if (arr[i] > max2 && arr[i] < max)
max2 = arr[i];
if (arr[i] < min2 && arr[i] > min)
min2 = arr[i];
}
printf("Max = %.2f\nMax2 = %.2f\nMin = %.2f\nMin2 = %.2f", max, max2, min, min2);
getch();
return 0;
}
Upvotes: 0
Views: 280
Reputation: 153338
Only 1 pass needed. Compare each value to the not-so-extreme value first.
Use >=
and <=
if ties are allowed.
max2 = -FLT_MAX; // greatest
max = -FLT_MAX; // almost greatest
min = FLT_MAX; // almost least
min2 = FLT_MAX; // least
for (i = 0; i < 11; i++){
if (arr[i] > max) {
max = arr[i];
if (max > max2) {
max = max2;
max2 = arr[i];
}
}
if (arr[i] < min) {
min = arr[i];
if (min < min2) {
min = min2;
min2 = arr[i];
}
}
}
printf("Max = %.2f\nMax2 = %.2f\nMin = %.2f\nMin2 = %.2f", max, max2, min, min2);
A nifty approach uses NAN
- not a number. Notice the !(a<=b)
rather than (a>b)
. Because of NAN
, these are different. Comparing to NAN
is always false, even NAN == NAN
is false. With !(a<=b)
, the compare is true when a
is greater than b
or if a
is NAN
or if b
is NAN
.
Notes: Only maximum half of the problem shown. 0.0/0.0 --> NAN.
// Initialize both to NAN
max2 = 0.0f/0.0f; // greatest
max = 0.0f/0.0f; // almost greatest
for (i = 0; i < 11; i++) {
if (!(arr[i] <= max)) {
max = arr[i];
if (!(max <= max2)) {
max = max2;
max2 = arr[i];
}
}
}
printf("Max = %.2f\nMax2 = %.2f\n", max, max2);
Upvotes: 0
Reputation: 20520
You could sort it, but that will be O(n log n) if the array gets any larger. It's pretty irrelevant for 11 elements, though, and if you're certain it'll always be 11, then sorting would be the easiest method.
Failing that, the simplest way, from the perspective of understanding the code, would be:
In terms of the code you have, the problem is here:
while (min == min2){
min2 = arr[1 + i];
i++;
}
This is after your first loop, where i
ran from 1 to 10. At the end of the loop, the value of i
would have been 11. But now you're keeping scanning, and i
is still increasing... you've run past the end of the array!
Upvotes: 2
Reputation: 234645
You are effectively having to sort 4 elements from a population of 11. You also have to deal with edge cases like extreme elements being equal.
That all considered, consider sorting the array (use qsort
) then pull out the first two and last two elements as your answer.
Indeed you are unnecessarily sorting 7 elements, but, in compensation, your code will be stable as it makes use of a standard library function to do the hard work. The logarithmic algorithm of qsort
will not penalise you too much for that, as 4 and 11 are of similar magnitude in logarithmic space.
Of course, if the population size increases so O(N Log N) becomes large then you might have to switch to a hand-coded solution if your use-case demands that.
Upvotes: 1
Reputation: 1349
I think you need to reinit the value of i
before this part of code. It's out of your array bound, because after previous for loop value of i
is 11
.
while (min == min2){
min2 = arr[1 + i];
i++;
}
add i = 0
before that.
Also note that part of code will go infinitly when all float in this array are equal.
Upvotes: 0