如何将元素添加到排序列表中..?(C++)
How to add elements to a sorted list ...? (C++)
我刚刚第一次接触std::vector,现在我想改变使用纯C风格数组的坏习惯。我发现std::list是排序时要使用的容器。然而,我不是100%如何完成以下:
我正在做一些计算,其结果取决于两个指数(I和j)。最后,我只对100个最小的结果感兴趣(不一定是100个,但肯定比我计算值的总数小得多,在下面的代码中是m*n)。
const int L = 100;
int i_list[L];
int j_list[L];
double value_list[L];
for (int i=0;i<m;i++){
for (int j=0;j<n;j++){
double x = doSomeCalculations(i,j);
insertTheValueAndIndices(i,j,x,i_list,j_list,value_list);
}
}
完成后,value_list应包含100个最小值(按升序),i_list/j_list应列出相应的索引。我有一个工作版本的"insertValuesAndIndices()",但在那里我使用了纯数组和插入新值的最低效的方法。在写作过程中,我意识到我实际上有两个不同的问题:
计算值的数量(m*n)远远大于我想保留在列表中的数量,因此简单地保留所有值并最终只排序一次并不是一个真正的选择。另一方面,我只需要最后按正确的顺序对结果进行排序,所以也许有一种方法可以只对列表进行一次排序。对于这种排序,有什么"标准"的聪明高效的方法吗?
即使我可以存储所有结果并在之后进行排序,我也不知道如何使用std::list.sort()以正确的顺序获取索引数组。我想到的是定义一些包含结果和两个索引的类,将这些元素放在列表中,然后使用只检查值的比较器进行排序。然而,也许还有一种更直接的方法可以做到这一点?
干杯&提前感谢
首先,您可能不想要std::list
,而是想要std::vector
。然后使用std::lower_bound
查找插入位置,如果结果向量包含的元素数超过你感兴趣的std::vector<>::pop_back
额外的一个。
感谢您的评论。由于我的帖子没有提出一个明确的问题,但它恰恰表明了我对如何解决问题的无知;),我想发表我的结论和一个工作的例子。。。
首先,感谢您的澄清,"std::list是排序时要使用的容器"不是真的。正如James Kanze所指出的那样,std::vector也能完成这项工作。其次,如果我只是在正确的位置"插入"新值,我真的不必对向量进行"排序"。此外,没有人反对我关于如何对指数进行排序的想法,以下是我的解决方案:
#include <cfloat>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
struct MyValue{
MyValue(double v,int f,int s):value(v),first(f),second(s){}
double value;
int first;
int second;
};
bool compareValues(const MyValue a,const MyValue b){return a.value < b.value;}
void insertMyValue(std::vector<MyValue>* v,MyValue x,int maxSize){
v->insert(std::lower_bound(v->begin(),v->end(),x,compareValues),x);
if (v->size()>maxSize){v->erase(v->end()-1);}
}
void main(){
const int imax = 10;
const int jmax = 10;
const int Nmax = 30;
std::vector<MyValue> results;
results.reserve(Nmax+1);
// Fill the vector
for (int i=0;i<imax;i++){
for (int j=0;j<jmax;j++){
double result = i*(j+0.1);
insertMyValue(&results,MyValue(result,i,j),Nmax);
}
}
// Print it
for (std::vector<MyValue>::iterator it = results.begin();it<results.end();it++){
cout << (*it).first << " " << (*it).second << " " << (*it).value << endl;
}
}
排序是个坏主意。
而是使用std::vector<int> buffer(count);
来存储std::make_heap
。
然后执行:
template<class T>
void add_element( std::vector<T>& heap, T element, size_t size ) {
heap.push_back(element);
std::push_heap(heap.begin(), heap.end());
while (heap.size() > size) {
std::pop_heap(heap.begin(), heap.end());
heap.pop_back();
}
}
它采用vector
形式的堆(空的vector
是堆),并添加一个元素,然后弹出任何超过堆限制的元素。
这将适用于任何具有operator<
的T
。push_heap
和pop_heap
也有自定义比较器版本。
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 通过for循环使用用户输入填充列表
- C++:如何使函数只返回作为列表一部分的字符串
- 概念中的cv限定符需要表达式参数列表
- 下面是我为检测链接列表中的循环而制作的代码
- 建议在运行时将带有类实例的列表从c++导入qml
- 如何维护资源管理器项目视图中当前可见的项目列表
- 在卡萨布兰卡形成编码参数的列表
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题