简体   繁体   中英

C find the 2 largest numbers and 2 smallest numbers in float array

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;

}

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:

  1. Make one pass through the array to identify the min and the max. Record not just the min and max, but their locations too.
  2. Make another pass through the array, and find the min and max, but ignoring the elements you found in the first pass.

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!

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM