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

时间:2013-06-23 08:07:46

标签: c++

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

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

我尽我所能;但每次执行algo2()函数时,它都会停止执行。非常感谢您的帮助。谢谢。

    #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;
    }

3 个答案:

答案 0 :(得分:1)

这是工作代码。你需要删除你正在考虑的元素。

快点: 你的排序工作正常,但我把它改成了我熟悉的方式。忽略了分拣机功能的变化。 专注于algo2功能。

#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;
}

答案 1 :(得分:1)

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

如果找到更大的元素,则将其插入适当位置的向量中,然后从第一个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);
}

答案 2 :(得分:0)

我认为这是找到第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;
}