我正在尝试创建一个函数来获取向量中的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 =冒泡排序
答案 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()
)。
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
个元素的通用解决方案:
topElements
元素创建长度为N
的数组或向量N
。topElements
的每个元素初始化为向量中第一个元素的值。topElements[0]
,请将topElements[0]
替换为元素的值。否则,请转到3. i
= 0开始,如果topElements[i]
大于topElements[i + 1]
,请与topElements[i]
交换topElements[i + 1]
。i
小于N
,但请增加i
并转到5。这会导致topElements
以与值相反的顺序包含您的前N
个元素 - 也就是说,最大值位于topElements[N - 1]
。