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

时间:2014-10-31 13:30:38

标签: c++ arrays sorting

我刚刚第一次接触到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相应的索引。我有&#34; insertValuesAndIndices()&#34;的工作版本,但在那里我使用普通数组和插入新值的最低效方法。在写作的过程中,我意识到我实际上有两个截然不同的问题:

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

  2. 即使我可以存储所有结果并在之后进行排序,我也不确定如何使用std :: list.sort()以正确的顺序获取索引数组。我想到的是定义一些包含结果和两个索引的类,将这些元素放在一个列表中,然后使用一个只检查值来进行排序的比较器。但是,也许有一种更简单的方法可以做同样的事情吗?

  3. 干杯&amp;提前致谢

3 个答案:

答案 0 :(得分:5)

首先,您可能不想要std::list,但需要std::vector。 然后使用std::lower_bound查找要插入的位置,以及是否插入 结果向量包含多于元素的数量 你感兴趣,std::vector<>::pop_back要摆脱 额外的一个。

答案 1 :(得分:0)

感谢您的评论。由于我的帖子没有陈述一个明确定义的问题,但它反而证明了我对如何解决我的问题的无知;),我想发布我的结论和一个有效的例子......

首先,感谢澄清,&#34; std :: list是排序时使用的容器&#34; 不是真的。正如所指出的,通过James Kanze,std :: vector也能完成这项工作。其次,我真的没有&#34;排序&#34;如果我只是&#34;插入&#34;在正确的地方新的价值观。此外,没有人反对我的想法如何使索引也排序,这是我的解决方案:

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

答案 2 :(得分:0)

排序是一个坏主意。

而是使用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是堆),并添加一个元素,然后弹出超过堆限制的任何元素。

这适用于T的任何operator<。还有push_heappop_heap的自定义比较器版本。