如何将元素添加到排序列表中..?(C++)

How to add elements to a sorted list ...? (C++)

本文关键字:C++ 列表 排序 元素 添加      更新时间:2023-10-16

我刚刚第一次接触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()",但在那里我使用了纯数组和插入新值的最低效的方法。在写作过程中,我意识到我实际上有两个不同的问题:

  1. 计算值的数量(m*n)远远大于我想保留在列表中的数量,因此简单地保留所有值并最终只排序一次并不是一个真正的选择。另一方面,我只需要最后按正确的顺序对结果进行排序,所以也许有一种方法可以只对列表进行一次排序。对于这种排序,有什么"标准"的聪明高效的方法吗?

  2. 即使我可以存储所有结果并在之后进行排序,我也不知道如何使用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<Tpush_heappop_heap也有自定义比较器版本。