找出前三个整数

Find top three integer numbers

我需要在不使用数组的情况下找到 10 个整数中的前 3 个。 我必须找到它们的索引并使用索引打印数组编号。

例如,如果数组是 {0,1,2,3,4,5,6,7,8,9};

我必须找到 first=9、second=8、third=7 并将数组打印为:

数组[第一个]

数组[秒]

数组[第三].

#include <stdio.h>
int main() {
  double arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  double s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8,
         s9 = 9;
  int first = 0, second=0,third=0;
  for (i = 0; i < 10; i++) {
    if (s1 >= s0 && s1 >= s2 && s1 >= s3 && s1 >= s4 && s1 >= s5 && s1 >= s6 &&
        s1 >= s7 && s1 >= s8 && s1 >= s9)
      first = 1;
    if (s2 >= s0 && s2 >= s1 && s2 >= s3 && s2 >= s4 && s2 >= s5 && s2 >= s6 &&
        s2 >= s7 && s2 >= s8 && s2 >= s9)
      first = 2;
    if (s3 >= s0 && s3 >= s1 && s3 >= s2 && s3 >= s4 && s3 >= s5 && s3 >= s6 &&
        s3 >= s7 && s3 >= s8 && s3 >= s9)
      first = 3;
    if (s4 >= s0 && s4 >= s1 && s4 >= s2 && s4 >= s3 && s4 >= s5 && s4 >= s6 &&
        s4 >= s7 && s4 >= s8 && s4 >= s9)
      first = 4;
    if (s5 >= s0 && s5 >= s1 && s5 >= s2 && s5 >= s3 && s5 >= s4 && s5 >= s6 &&
        s5 >= s7 && s5 >= s8 && s5 >= s9)
      first = 5;
    if (s6 >= s0 && s6 >= s1 && s6 >= s2 && s6 >= s3 && s6 >= s4 && s6 >= s5 &&
        s6 >= s7 && s6 >= s8 && s6 >= s9)
      first = 6;
    if (s7 >= s0 && s7 >= s1 && s7 >= s2 && s7 >= s3 && s7 >= s4 && s7 >= s5 &&
        s7 >= s6 && s7 >= s8 && s7 >= s9)
      first = 7;
    if (s8 >= s0 && s8 >= s1 && s8 >= s2 && s8 >= s3 && s8 >= s4 && s8 >= s5 &&
        s8 >= s6 && s8 >= s7 && s8 >= s9)
      first = 8;
    if (s9 >= s0 && s9 >= s1 && s9 >= s2 && s9 >= s3 && s9 >= s4 && s9 >= s5 &&
        s9 >= s6 && s9 >= s7 && s9 >= s8)
      first = 9;
  }
  printf("First: %g", arr[first]);
  return 0;
}

这将找到数组的第一个元素。我怎么能找到第二个和第三个元素?不使用数组的限制使这变得困难。

这是一个不错的算法

int* top_3(const int* arr_of_10) {
  static int top_3[3];
  int next_highest = 0;
  
  for (int appended = 0; appended < 3; appended++) {
    int highest_of = 0;
    for (int index = 0; index < 10; index++) {
      if ((highest < arr_of_10[index]) && ((highest < next_highest) || !next_highest)) {
        highest = arr_of_10[index];
      }
    }
    top_3[appended] = highest;
    next_highest = highest;
  }
  return top_3;
}

这里有一种简单的方法,它遍历每个元素,并将其向上移动到第三、第二和第一的排名,直到保持该排名的索引指向更大或相等的值。你会注意到我正在用 -1 初始化索引,我这样做是因为如果它们都以 0 开头并且 0 位于前 2 个(如果它是第三个就没问题),那么没有其他数字会替换它并且你的前三名都是初始值,即使只有一个值。 (我将在下面添加另一个解决方法)

#include <stdio.h>

int main() {

    int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int first = -1, second = -1, third = -1;

    int temp;
    for (int i = 0; i < 10; i++) {
        if (third == -1 || arr[i] > arr[third]) { //greater than third
            third = i;
            if (second == -1 || arr[i] > arr[second]) { //than second
                temp = second;
                second = third;
                third = temp;
                if (first == -1 || arr[i] > arr[first]) { //than first
                    temp = first;
                    first = second;
                    second = temp;
                }
            }
        }
    }

    printf("First: %d\n", arr[first]);
    printf("Second: %d\n", arr[second]);
    printf("Third: %d\n", arr[third]);

    return 0;
}

你会注意到每个if语句首先要检查排名是否还没有被填充(== -1),这是不理想的。为了避免这种情况,我们可以将三个等级初始化为指向最小值,这需要计算能力才能找到,但如果算上整数比较,则更少。

//find index of the min
int min = 0;
for (int i = 0; i < 10; i++) {
    if (arr[i] < arr[min]) {
        min = i;
    }
}

//set each rank to the index of the min
int first = min, second = min, third = min;

这将被插入到第一个代码块中,以代替三个等级的原始初始化。然后,您就可以删除 if 语句中出现的三个 rank == -1 ||

这有点愚蠢,但考虑到您的限制,这样的做法怎么样?

    public static void Main()
    {
        double s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6, s7 = 7, s8 = 8, s9 = 9;
        var arr = new double[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        int first = 0, second=0, third=0;
        
        first = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, -1, -1);
        second = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, first, -1);
        third = FindMax(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, first, second);
        
        Console.WriteLine(arr[first]);
        Console.WriteLine(arr[second]);
        Console.WriteLine(arr[third]);
    }

    private static int FindMax(
        double s0, 
        double s1, 
        double s2, 
        double s3, 
        double s4, 
        double s5, 
        double s6, 
        double s7, 
        double s8,
        double s9,
        int indexOneToIgnore,
        int indexTwoToIgnore){
        
        double max = 0;
        int indexOfMax = 0;
        
        if(Math.Max(max, s0) > max && indexOneToIgnore != 0 && indexTwoToIgnore != 0)
        {
            max = s0;
            indexOfMax = 0;
        }
        if(Math.Max(max, s1) > max && indexOneToIgnore != 1 && indexTwoToIgnore != 1)
        {
            max = s1;
            indexOfMax = 1;
        }
        if(Math.Max(max, s2) > max && indexOneToIgnore != 2 && indexTwoToIgnore != 2)
        {
            max = s2;
            indexOfMax = 2;
        }


...

        return indexOfMax;
    }

完整示例在这里:.Net Fiddle.

可以通过将 if 语句移动到一个单独的函数来缩短很多,但是由于无论如何你都需要将它采用到 C++,所以我把它留给你。

这是我的解决方案:

#include <stdio.h>
#include <float.h>

int main( void )
{
    double arr[] =
        { 17.1, 12.3, 7.2, 35.7, 14.2, 12.4, 6.9, 19.1, 34.9, 5.5 };

    //This declaration has been modified to use the array only to
    //ensure consistency with the array. I do not consider this to
    //be cheating. This declaration can be replaced with the
    //original code and the program will still work.
    double
        s0 = arr[0], s1 = arr[1], s2 = arr[2], s3 = arr[3],
        s4 = arr[4], s5 = arr[5], s6 = arr[6], s7 = arr[7],
        s8 = arr[8], s9 = arr[9];

    int first = 0, second = 0, third = 0;

    for ( int i = 0; i < 3; i++ )
    {
        int largest_index;
        double *p_largest;

        for ( int j = 0; j < 10; j++ )
        {
            double *p;

            //the following loop effectively does "p = &arr[j]", without
            //actually using the array, but instead making the pointer
            //point to the corresponding lone variable instead
            switch ( j )
            {
                case 0:
                    p = &s0;
                    break;
                case 1:
                    p = &s1;
                    break;
                case 2:
                    p = &s2;
                    break;
                case 3:
                    p = &s3;
                    break;
                case 4:
                    p = &s4;
                    break;
                case 5:
                    p = &s5;
                    break;
                case 6:
                    p = &s6;
                    break;
                case 7:
                    p = &s7;
                    break;
                case 8:
                    p = &s8;
                    break;
                case 9:
                    p = &s9;
                    break;
           }

           //determine whether *p is the largest value in the
           //array
           if (
                *p >= s0 && *p >= s1 && *p >= s2 && *p >= s3 &&
                *p >= s4 && *p >= s5 && *p >= s6 && *p >= s7 &&
                *p >= s8 && *p >= s9
            )
            {
                largest_index = j;
            }
        }

        //This "switch" statement effectively does
        //"p_largest = &arr[largest_index];", but does not
        //point inside the array. Instead, it points to the
        //corresponding lone variable.
        switch ( largest_index )
        {
            case 0:
                p_largest = &s0;
                break;
            case 1:
                p_largest = &s1;
                break;
            case 2:
                p_largest = &s2;
                break;
            case 3:
                p_largest = &s3;
                break;
            case 4:
                p_largest = &s4;
                break;
            case 5:
                p_largest = &s5;
                break;
            case 6:
                p_largest = &s6;
                break;
            case 7:
                p_largest = &s7;
                break;
            case 8:
                p_largest = &s8;
                break;
            case 9:
                p_largest = &s9;
                break;
        }

        //set "first", "second" or "third", depending on which
        //loop iteration we currently are in
        switch ( i )
        {
            case 0:
                first  = largest_index;
                break;
            case 1:
                second = largest_index;
                break;
            case 2:
                third  = largest_index;
                break;
        }

        //set highest number to lowest possible number, so that
        //it won't be the highest again in the next iteration of
        //the loop
        *p_largest = -DBL_MAX;
    }

    printf( "First:  %g\n", arr[first] );
    printf( "Second: %g\n", arr[second] );
    printf( "Third:  %g\n", arr[third] );
}

这个程序有以下(正确的)输出:

First:  35.7
Second: 34.9
Third:  19.1

此解决方案的工作原理是将找到的最高值设置为可能的最低值(即 -DBL_MAX),这样循环的下一次迭代将不会再次找到与最高值相同的值,但是而是会找到下一个最高值。

为了进行比较,这是我使用数组代替的更简洁的解决方案:

#include <stdio.h>
#include <float.h>

int main( void )
{
    double arr[] =
        { 17.1, 12.3, 7.2, 35.7, 14.2, 12.4, 6.9, 19.1, 34.9, 5.5 };

    double largest_values[3];

    for ( int i = 0; i < 3; i++ )
    {
        double largest_value = -DBL_MAX;
        int largest_index;

        for ( int j = 0; j < 10; j++ )
        {
            if ( arr[j] >= largest_value )
            {
                largest_value = arr[j];
                largest_index = j;
            }
        }

        largest_values[i] = largest_value;
        arr[largest_index] = -DBL_MAX;
    }

    printf( "First:  %g\n", largest_values[0] );
    printf( "Second: %g\n", largest_values[1] );
    printf( "Third:  %g\n", largest_values[2] );
}