给定一系列整数,提供第k个最大数

Given series of integers, provide the kth largest number

本文关键字:最大数 一系列 整数      更新时间:2023-10-16

请帮我找出我的alg2()函数有什么问题。算法2的过程如下:

  • 将N个数字读入一个矢量
  • 按降序对矢量元素进行排序
  • 每一个剩余的元素被逐一读取
  • 当一个新元素到达时,如果它小于向量中的第k个元素,则忽略它
  • 否则,它将被放置在数组中的正确位置,将一个元素从向量中挤出
  • 最后,将打印第k个位置的元素

我已经尽力了;但每次我执行algorg2()函数时,它都会停止执行。非常感谢您的帮助。非常感谢。

    #include <iostream>
    #include <stdlib.h>
    #include <math.h>
    #include <vector>
    using namespace std;
    vector<int> input()
    {
        vector<int> nums;
        int input;
        cout << "Please enter some integers (type 12345 to end):n";
        do 
        {
            cin >> input;
            nums.push_back(input);
        }
        while(input!=12345);
        nums.pop_back(); //omits terminator value from the vector
        return nums;
    }
    vector<int> sorter(vector<int> nums,int ilan)
    {
        int index,ctr;
        for(ctr=1;ctr<=pow((ilan-1),2);ctr++)
        {
            for(index=1;index<ilan;index++)
            {
                if(nums[index]>nums[index-1])
                {
                    nums[index]+=nums[index-1];
                    nums[index-1]=nums[index]-nums[index-1];
                    nums[index]-=nums[index-1];
                }
            }
        }
        return nums;
    }
    void cardinal(int k)
    {
        if(k==11||k==12||k==13)
            cout << "th";
        else
        {
            while(k>10)
            {
                k=k%10;
            }
            switch(k)
            {
                case 1: {cout << "st"; break;}
                case 2: {cout << "nd"; break;}
                case 3: {cout << "rd"; break;}
                default: cout << "th";
            }
        }
    }
    void output(vector<int> nums,int k)
    {
        cout << "The " << k;
        cardinal(k);
        cout << " largest number is " << nums[k-1];
    }
    void algo2(vector<int> nums,int k)
    {
        int index;
        int cursor;
        nums = sorter(nums,k);
        for(cursor=k;cursor+1<nums.size();)
        {
            if(nums[k-1]<nums[cursor])
            {
                for(index=0;index<(k-1);index++)
                {
                    if(nums[cursor]>nums[index])
                    {
                        nums.insert(nums.begin()+index,nums[cursor]);
                        if(k+2==nums.size())
                            nums.erase(nums.begin()+k+1);
                        else
                            nums.erase(nums.begin()+k,nums.begin()+k+1);
                        break;
                    }   
                }
            }
            else
            {
                nums.erase(nums.begin()+cursor);
                break;
            }
        }
        output(nums,k);
    }
    int main()
    {
        vector<int> nums;
        int choice=0, k=0;
        cout << "Type the algorithm number you'll use (1 or 2): ";
        cin >> choice;
        cout << "Input k: ";
        cin >> k;
        //Algorithm 1
        if(choice==1)
        {
            nums = input();
            nums = sorter(nums,nums.size());
            output(nums,k);
        }
        //Algorithm 2
        else if(choice==2)
        {
            nums = input();
            algo2(nums,k);
        }
        cout << endl << endl;
        system("pause");
        return 0;
    }

这是工作代码。您需要擦除您现在正在考虑的元素。

快速要点:您的排序工作正常,但我已将其更改为我熟悉的方式。忽略排序功能中的更改。专注于alg2函数。

#include <iostream>
#include <stdlib.h>
#include <math.h>
#include<conio.h>
#include <vector>
using namespace std;
vector<int> input()
{
    vector<int> nums;
    int input;
    cout << "Please enter some integers (type 12345 to end):n";
    do 
    {
        cin >> input;
        nums.push_back(input);
    }
    while(input!=12345);
    nums.pop_back(); //omits terminator value from the vector
    return nums;
}
vector<int> sorter(vector<int> nums,int ilan)
{
    int index,ctr;
    for(ctr=0;ctr<ilan;ctr++)
    {
        for(index=ctr+1;index<ilan;index++)
        {
            if(nums[index]>nums[index-1])
            {
                nums[index]+=nums[index-1];
                nums[index-1]=nums[index]-nums[index-1];
                nums[index]-=nums[index-1];
            }
        }
    }
    cout<<"n";
    for(int i=0;i<ilan;i++)
     cout<<nums[i]<<" ";
    getch(); 
    return nums;
}
void cardinal(int k)
{
    if(k==11||k==12||k==13)
        cout << "th";
    else
    {
        while(k>10)
        {
            k=k%10;
        }
        switch(k)
        {
            case 1: {cout << "st"; break;}
            case 2: {cout << "nd"; break;}
            case 3: {cout << "rd"; break;}
            default: cout << "th";
        }
    }
}
void output(vector<int> nums,int k)
{
    cout << "The " << k;
    cardinal(k);
    cout << " largest number is " << nums[k-1];
}
void algo2(vector<int> nums,int k)
{
    int index;
    int cursor;
    nums = sorter(nums,k);
    while(k<nums.size())
    {
        int t=nums[k];
        nums.erase(nums.begin()+k);                
        if(nums[k-1]<t)
        {
            for(index=0;index<=(k-1);index++)
            {
                if(t>nums[index])
                {
                    nums.insert(nums.begin()+index,t);
                    nums.erase(nums.begin()+k);
                    break;
                }   
            }
        }
    }
    output(nums,k);
}
int main()
{
    vector<int> nums;
    int choice=0, k=0;
    cout << "Type the algorithm number you'll use (1 or 2): ";
    cin >> choice;
    cout << "Input k: ";
    cin >> k;
    //Algorithm 1
    if(choice==1)
    {
        nums = input();
        nums = sorter(nums,nums.size());
        output(nums,k);
    }
    //Algorithm 2
    else if(choice==2)
    {
        nums = input();
        algo2(nums,k);
    }
    cout << endl << endl;
    system("pause");
    return 0;
}

好的,我现在发现了问题:

如果找到一个较大的元素,则将其插入向量中适当的位置,然后从第一个k(现在位于位置k)中删除最小的元素。到目前为止,一切都很好。但是,您可以而不是从向量的其余部分删除刚在开头插入的元素。因此,在下一次迭代中,它会再次找到完全相同的元素。因为如果元素等于所找到的元素,那么结果就是一个无休止的循环。

无论如何,这里有一个算法,它在更正后基本上与您的算法相同,但利用了标准库设施(当然,除了利用预先制作的nth_element算法外:-))。另一个变化是我添加了一些错误检查。我没有改变的是,你的算法会输出。通常情况下,算法应该只返回其结果,并将其留给调用者如何处理

void algo2_improved(std::vector<int> num, int k)
{
  if (num.size() < k)
  {
    std::cout << "there are too few elements in the vector!n";
    return;
  }
  std::sort(num.begin(), num.begin()+k, std::greater<int>());
  while (num.size() > k)
  {
    if (num[k] >= num[k-1])
      std::rotate(std::upper_bound(num.begin(),
                                   num_begin()+k,
                                   num[k],
                                   std::greater<int>()),
                  num.begin()+k,
                  num.begin()+k+1);
    num.erase(num.begin()+k);
  }
  output(num, k);
}

我认为这是找到第K个最大数的最佳方法。

#include "stdafx.h"
#include <iostream>
#include <algorithm>
using namespace std;
int partion(int arr[], int left, int right)
{
    int i = left;
    int j = right;
    int target = arr[i];
    while (i < j)
    {
        if (arr[j] > target)
            j--;
        arr[i] = arr[j];
        if (arr[i] <= target)
            i++;
        arr[j] = arr[i];
    }
    arr[j] = target;
    return j;
}

void quickSort(int arr[], int start, int end)
{
    if(start >= end)
        return;
    int pos = partion(arr, start, end);
    quickSort(arr, start, pos);
    quickSort(arr, pos+1, end);
}
int kth_element(int arr[], int start, int end, int k)
{
    int pos = partion(arr, start, end);
    if (pos == k)
        return arr[pos];
    else if (pos < k)
        kth_element(arr, pos + 1, end, k);
    else
        kth_element(arr, start, pos, k);
}
struct print
{
    void operator()(int a)
    {
        cout<<a<<" ";
    }
};
int main()
{
    int arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    int len = sizeof(arr) / sizeof(*arr);
    quickSort(arr, 0, len - 1);
    for_each(arr, arr + len, print());
    cout<<endl;
    cout<<"k = 2:  "<<kth_element(arr, 0, len - 1, len - 2)<<endl;
}