【问题标题】:Kth largest number in an array using "Sort K number of elements based array" algorithm使用“基于数组的 K 个元素排序”算法的数组中的第 K 个最大数
【发布时间】:2019-10-14 08:03:23
【问题描述】:

我正在尝试实现以下算法来查找文本文件中给出的第 k 个最大输入数。第一个数字确定 k 变量,下一个数字确定元素的总数 (N),其余的是数字列表。 算法描述为:

  • 仅存储数组中的前 k 个数字
  • 按降序对数组进行排序,例如,使用插入排序
  • 一一阅读其余数字:
  • 如果小于数组中第k个位置的数字则忽略
  • 否则;将其插入数组中的正确位置并移动 剩余数字(第k个位置的数字将被抛出 数组外)
  • 返回数组中索引 k-1 处的数字。

AlgorithmSortK::AlgorithmSortK(int k) : SelectionAlgorithm(k)
{
    this->k = k;

}



int AlgorithmSortK::select()
{

    int N = 0;
    int x=0;
    int *pNums = 0;
    cin>>N;
    cout<<"N:"<<N<<endl;
    pNums = new int[N];
     int key, j;
    for (int i=0; i<k; i++)
    {
        cin>>x;
        pNums[i] = x;
        cout<<pNums[i]<<endl;



        for (i = 1; i <k; i++)
        {
            key = pNums[i];
            j = i - 1;
            while (j >= 0 && pNums[j] <key)
            {
                pNums[j + 1] = pNums[j];
                j = j - 1;
            }
            pNums[j + 1] = key;
        }

        for ( i=k; i<N; i++)
        {
            cin>>x;

            if(x>pNums[k-1])
            {

                for (int shifter=0; shifter<k; shifter++)
                {
                    pNums[shifter]=x;

                    pNums[shifter] =  pNums[shifter+1];

                }
                for (int r = 1; r <k; r++)
                {

                    key = pNums[r];
                    j = r - 1;
                    while (j >= 0 && pNums[j] <key)
                    {
                        pNums[j + 1] = pNums[j];
                        j = j - 1;
                    }
                    pNums[j + 1] = key;

                }
            }
        }
        cout<<"pNums[k-1]:"<<pNums[k-1]<<endl;
    }

这是我的代码,它可以正确编译,但 pNums[k-1] 的结果不同且不正确。我认为我在 k-1 索引操作中错误地移动和删除了元素。 N 是元素的总数,我正在对 k 限制数组使用插入排序。

【问题讨论】:

  • pNums = new int[N]”。想法是只存储K元素,所以你已经可以在这里减小大小了。
  • 看来你的第一个循环不应该包含其他循环。
  • 第一个 for 循环的 {} 括号似乎有问题

标签: c++ arrays algorithm pointers


【解决方案1】:

这应该会有所帮助:

int AlgorithmSortK::select()
{
    int N, x;

    cin >> N;    // number of the input elements
    cout << "N:" << N << endl;

    std::vector<int> nums;
    nums.resize( k, std::numeric_limits<int>::min() );    // assume 'k' is defined elsewhere

    for(int i=0; i<N; i++)
    {
        cin >> x;  // get the next element

        // shift it down while it's larger than existing numbers
        for( int j=0; j<k; j++) {
            if( x > nums[j] ) {
                std::swap( x, nums[j] );
            }
        }
    }
    cout<<"nums[k-1]:" << nums[k-1]<<endl;
}

复杂度是O(N*k),可以让它更快,但我宁愿让它更简单。

【讨论】:

  • @Jarod42 nums.resize( k ); -> nums.resize( k, NEGATIVE_NUMBER );
  • 感谢您的解决方案。它工作正常!但是由于我是 C++ 的基础,所以我尝试显式地使用动态分配。之前没有尝试使用 Vector 和 Limits 库。我想我需要在操作完成后从内存中释放向量。
  • @utdlegend 请不要使用动态分配。 std::vector 将自行管理记忆,您无需担心任何事情。使用动态内存分配,您会时不时地在脚下开枪。使用numeric limits 有点傻,但是Jarod42 坚持认为,如果你写一个简单的样本并且不打算使用很多负数,你可以跳过那部分,只留下nums.resize( k )
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多