【问题标题】:how to find/print 'n' largest element of array?如何查找/打印数组的“n”个最大元素?
【发布时间】:2021-10-13 17:10:22
【问题描述】:

我的问题是从数组中打印 n 个最大元素。

  1. 使用循环
  2. 动态值(我更改了 2010 年 3 月 5 日的数组、长度和数字),
  3. 不使用数组排序或冒泡排序。
  4. 制作函数

我试过这个程序

#include <stdio.h>
int main()
{
    int length;
    int data[] = {5, -2, 0, -3, 3}; //.it can be changable
    length = sizeof(data) / sizeof(int);
    int i = 0;
    int number = 3; //.it mean print how many largest number to print.
    int temp;
    
    for (i = 0; i < length; i++)
    {
        if (data[i] > data[i+1])
        {
            temp = data[i];
            data[i] = data[i+1];
            data[i+1] = temp;
            
        }
        else
        {
            temp = data[i+1];
            data[i+1] = data[i];
            data[i] = temp;
        }
    }
    printf("%d",data[i]);

    return 0;
}

我的输出是 3。

【问题讨论】:

  • 您的循环正在对数组进行排序。
  • @kaylum 我认为他们的意思是第 N 大。
  • 实际上,您的循环交换了 ifelse 块中的元素。
  • @Barmar 我希望你能理解我的回答,告诉我以代码类型而不是第 N 个最大的数字回答我必须得到 N 个最大的数字
  • @S.G 评论for (i = 0; i &lt; length; i++) { if (data[i] &gt; data[i+1])data[i+1] 可以访问数组外。

标签: arrays c function


【解决方案1】:

您可以使用quickselect 算法来查找无序数组中的第 n 个最大元素。它基于快速排序排序算法,但不是进行完整的快速排序,而是在枢轴本身是第 n 个最大元素的点处停止。此外,它不会对枢轴的左右两侧进行递归,而只会对包含第n大元素的部分进行递归。

这是 C 中的一个实现:

#include <stdio.h>
#include <limits.h>

void swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

int partition(int arr[], int l, int r)
{
    // use last element as pivot
    int x = arr[r], i = l;

    // move larger elements to left of pivot and smaller elements to right of it
    for (int j = l; j <= r - 1; j++) {
        if (arr[j] >= x) {
            swap(&arr[i], &arr[j]);
            i++;
        }
    }
    swap(&arr[i], &arr[r]);
    return i;
}

int nthLargest(int arr[], int l, int r, int n)
{
    // if n is smaller than number of elements in array
    if (n > 0 && n <= r - l + 1) {

        // partition the array around last element
        int index = partition(arr, l, r);

        // if position is same as n, return element
        if (index - l == n - 1)
            return arr[index];

        // if position is more, recur for left subarray
        if (index - l > n - 1)
            return nthLargest(arr, l, index - 1, n);

        // otherwise recur for right subarray
        return nthLargest(arr, index + 1, r, n - index + l - 1);
    }

    return INT_MAX;
}

int main()
{
    int data[] = {5, -2, 0, -3, 3, 6, -6};
    int n = sizeof(data)/sizeof(int);
    printf("%d", nthLargest(data, 0, n - 1, 1));
    printf("\n");
    return 0;
}

输出:

6

Demo

快速选择的平均复杂度为 O(n),更糟糕的情况为 O(n^2)。

【讨论】:

  • 是排序方式,不是数组排序,也不是冒泡排序方式
  • @S.G 我认为这可能是可以接受的,因为它没有对数组进行完全排序。您可能会发现this 的问题很有趣。另一种可能的解决方案是构建一个最大堆。
【解决方案2】:

一个明显的解决方案是对数组进行排序,但是......

考虑到约束:

  1. 使用循环
  2. 数组大小和元素数量是动态的
  3. 不要使用数组排序或冒泡排序。
  4. 制作函数

你可以这样做:

void print_largest_ints(int* p, unsigned nelem, unsigned n)
{
    if (n == 0) return;
    if (n > nelem) n = nelem;
    unsigned index = 0;
    for (unsigned i = 1; i < nelem; ++i)
    {
        if (p[i] > p[index])
        {
            index = i;
        }   
    }
    
    printf("%d ", p[index]);
    int saved = p[index];
    p[index] = INT_MIN;
    print_largest_ints(p, nelem, n-1);
    p[index] = saved;
}

然后这样称呼它

int main(){
    int arr[] = {7, 3, 5, 9};
    unsigned elements_to_print = 2;
    print_largest_ints(arr, sizeof arr / sizeof arr[0], elements_to_print);
    return 0;
}

输出:

9 7

这应该符合您的约束,即

  • 在函数中实现 (#4)
  • 该函数可以接受任何数组大小和 N 值 (#2)
  • 该函数有一个循环 (#1)
  • 数组未排序 (#3)

函数执行时数组改变,但函数返回main时数组不变。

【讨论】:

  • INT_MIN 不是函数。它是一个值(即最小值和整数可以有)
  • 但不使用它。我知道这是我的工作,我制作这个程序来改进逻辑 int_min 就像一个捷径,如果你愿意,可以对我的问题投赞成票
  • 根据您的系统,您可以将 INT_MIN 替换为它的值,例如-2147483648如果你喜欢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-24
  • 2019-02-24
  • 2021-11-07
  • 2012-05-07
  • 2020-09-06
  • 1970-01-01
相关资源
最近更新 更多