找到向量中最大的3个数字

时间:2010-11-08 18:34:14

标签: c++ vector c++builder

我正在尝试创建一个函数来获取向量中的3个最大数字。例如: 数字:1 6 2 5 3 7 4 结果:5 6 7

我认为我可以对它们进行排序DESC,在开始时获取3个数字,然后使用ASC,但这会浪费内存分配和执行时间。我知道有一个更简单的解决方案,但我无法弄清楚。另一个问题是,如果我只有两个数字怎么办...

BTW:我使用编译器BorlandC ++ 3.1(我知道,很老了,但这就是我在考试中使用的内容......)

谢谢你们。

LE:如果有人想了解我正在努力完成的事情,你可以查看代码:

#include<fstream.h>
#include<conio.h>

int v[1000], n;
ifstream f("bac.in");

void citire();
void afisare_a();
int ultima_cifra(int nr);
void sortare(int asc);

void main() {
    clrscr();
    citire();
    sortare(2);
    afisare_a();
    getch();
}

void citire() {
    f>>n;
    for(int i = 0; i < n; i++)
        f>>v[i];
        f.close();
}                            

void afisare_a() {
    for(int i = 0;i < n; i++)
            if(ultima_cifra(v[i]) == 5)
            cout<<v[i]<<" ";
}

int ultima_cifra(int nr) {
    return nr - 10 * ( nr / 10 );
}

void sortare(int asc) {
    int aux, s;
        if(asc == 1)
        do {
            s = 0;
            for(int i = 0; i < n-1; i++)
                if(v[i] > v[i+1]) {
                    aux = v[i];
                    v[i] = v[i+1];
                    v[i+1] = aux;
                    s = 1;
                }
        } while( s == 1);
    else
        do {
            s = 0;
            for(int i = 0; i < n-1; i++)
                if(v[i] < v[i+1]) {
                    aux = v[i];
                    v[i] = v[i+1];
                    v[i+1] = v[i];
                                        s = 1;
                }
                } while(s == 1);
}

Citire =阅读 Afisare =显示 Ultima Cifra =数字的最后一位数 Sortare =冒泡排序

12 个答案:

答案 0 :(得分:15)

如果您使用的是现代编译器,则可以使用std::nth_element查找前三名。按原样,您必须扫描数组,跟踪到目前为止在任何给定时间看到的三个最大元素,当您到达结束时,这些将是您的答案。

对于要管理的三个要素是微不足道的。如果在N可能相当大的情况下你必须做N个最大(或最小)的元素,那么你几乎肯定想要使用Hoare的select算法,就像std::nth_element那样。

答案 1 :(得分:14)

你可以这样做而不需要排序,它可以在O(n)时间内使用线性搜索,3个变量可以保留3个最大数字(如果此向量不会改变,则保留最大数字的索引)。 / p>

答案 2 :(得分:4)

为什么不单步执行一次并跟踪遇到的最高位数?

编辑:输入的范围对于您想要跟踪3个最高位数非常重要。

答案 3 :(得分:3)

使用std::partial_sort对您关注的第一个c元素进行降序排序。对于给定数量的所需元素(n log c)时间,它将以线性时间运行。

答案 4 :(得分:2)

如果你不能使用std :: nth_element编写自己的选择函数。

您可以在此处阅读相关内容:http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements

答案 5 :(得分:1)

正常排序,然后使用rbegin()从后面迭代,尽可能多地提取(当然不超过rend())。

无论是ASC还是DESC,

sort都会发生,所以内存不是问题,因为你的容器元素是int,因此没有自己的封装内存来管理。 / p>

答案 6 :(得分:1)

是排序很好。特别适用于长或可变长度列表。

为什么要对它进行两次排序?第二种可能实际上效率很低(取决于使用的算法)。反向会更快,但为什么这样做呢?如果你想在最后按升序排列它们,那么先将它们按升序排序(并从最后获取数字)

答案 7 :(得分:0)

我认为您可以选择扫描三个最大元素的向量或对其进行排序(使用向量中的排序或将其复制到像集合一样的隐式排序容器中)。

答案 8 :(得分:0)

如果你可以控制数组填充,也许你可以添加有序的数字然后选择前3(即),否则你可以使用二叉树来执行搜索或只是使用线性搜索,因为birryree说...

答案 9 :(得分:0)

感谢@ nevets1219指出下面的代码只处理正数。

我还没有充分测试这段代码,但这是一个开始:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> nums;
    nums.push_back(1);
    nums.push_back(6);
    nums.push_back(2);
    nums.push_back(5);
    nums.push_back(3);
    nums.push_back(7);
    nums.push_back(4);

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

    for (int i = 0; i < nums.size(); i++)
    {
        if (nums.at(i) > first)
        {
            third = second;
            second = first;            
            first = nums.at(i);
        }
        else if (nums.at(i) > second)
        {
            third = second;
            second = nums.at(i);
        }
        else if (nums.at(i) > third)
        {
            third = nums.at(i);
        }
        std::cout << "1st: " << first << " 2nd: " << second << " 3rd: " << third << std::endl;

    }

    return 0;
}

答案 10 :(得分:0)

以下解法找到O(n)中的三个最大数字并保留它们的相对顺序:

std::vector<int>::iterator p = std::max_element(vec.begin(), vec.end());
int x = *p;
*p = std::numeric_limits<int>::min();

std::vector<int>::iterator q = std::max_element(vec.begin(), vec.end());
int y = *q;
*q = std::numeric_limits<int>::min();

int z = *std::max_element(vec.begin(), vec.end());

*q = y;   // restore original value
*p = x;   // restore original value

答案 11 :(得分:0)

向量的前N个元素的通用解决方案:

  1. 为您的热门topElements元素创建长度为N的数组或向量N
  2. topElements的每个元素初始化为向量中第一个元素的值。
  3. 选择向量中的下一个元素,如果没有剩余元素则完成。
  4. 如果所选元素大于topElements[0],请将topElements[0]替换为元素的值。否则,请转到3.
  5. i = 0开始,如果topElements[i]大于topElements[i + 1],请与topElements[i]交换topElements[i + 1]
  6. 虽然i小于N,但请增加i并转到5。
  7. 转到3。
  8. 这会导致topElements以与值相反的顺序包含您的前N个元素 - 也就是说,最大值位于topElements[N - 1]