提问者:小点点

函数返回向量最高值的前5个索引


有什么功能可以做到这一点吗?

我想提取一个索引中最高值的前5个索引。

我只能得到最高值的索引但是然后我必须删除它然后再做一次,还有其他方法吗?

for (unsigned i = 0; i < 5 ; i++){
     int index = std::distance(vMetric.begin(),std::max_element(vMetric.begin(), vMetric.end()));
     vMetric.erase(vMetric.begin()+ index);
}

共3个答案

匿名用户

创建索引数组并对其进行部分排序:

std::vector<size_t> indices(vMetric.size());
std::iota(indices.begin(), indices.end(), 0);
std::partial_sort(indices.begin(), indices.begin() + 5, indices.end(),
                  [&](size_t A, size_t B) {
                     return vMetric[A] > vMetric[B];
                  });

indexes的前5个元素包含您的答案,并且原始向量不变。

匿名用户

链接到代码https://onlinegdb.com/rjcys-sld

#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;

bool MyComp(pair<int,int> a, pair<int,int> b)
{
    if(a.first>=b.first) return true;
    return false;
}

int main()
{
    
    vector<int> vMetric={5,6,1,4,10};
    
    vector<pair<int,int>> vMetricWithIndex;
    
    for(int i=0;i<vMetric.size();++i) vMetricWithIndex.push_back({vMetric[i],i});
    
    sort(vMetricWithIndex.begin(),vMetricWithIndex.end(),MyComp);

    for(auto i:vMetricWithIndex)
    {
        cout<<"Element :"<<i.first<<" | Index:"<<i.second<<endl;
    }
    
    return 0;
}

逻辑:

  1. 只需创建一个对的向量,每个对的第一个元素作为vMetric元素,第二个元素作为此vMetric元素的索引。
  2. 现在按递减顺序对此vMetricWithIndex进行排序。 请注意,我们需要一个helper函数(如上面代码中的MyComp)来对向量对进行排序。
  3. 瞧! 前5对VMetricWithIndex的第二个元素表示所需的索引。

匿名用户

有几种可能的解决方案。 大多数答案建议创建数组或索引数组的(部分)排序副本。 然而,这可能需要大量额外的存储空间。 如果输入的大小非常大,那么额外的存储空间可能不再适合缓存,然后这可能变得很慢。

作为另一种选择,您可以只扫描输入数组一次,并保留一组迄今所见的最大元素的5个索引。 下面是一个可能的实现,它更通用一点,可以在任何提供转发器的容器上工作:

template<typename Iterator>
std::vector<size_t> n_largest_indices(Iterator it, Iterator end, size_t n) {
    struct Element {
        Iterator it;
        size_t index;
    };

    std::vector<Element> top_elements;
    top_elements.reserve(n + 1);

    for(size_t index = 0; it != end; ++index, ++it) {
        top_elements.insert(std::upper_bound(top_elements.begin(), top_elements.end(), *it, [](auto value, auto element){return value > *element.it;}), {it, index});
        if (index >= n)
            top_elements.pop_back();
    }

    std::vector<size_t> result;
    result.reserve(top_elements.size());

    for(auto &element: top_elements)
        result.push_back(element.index);

    return result;
}

上面的方法可能可以进一步改进,并专门用于RandomAccessIterator,这样您就不需要有一个结构元素,而只需要存储顶部的N索引。 还可以很容易地修改它以返回N最大值本身,或者将迭代器返回到N最大值。

示例用法:

std::vector<int> v{1, 35, 12, 69, 2, 5,1, 6, 99, 53, 2};
auto indices = n_largest_indices(v.begin(), v.end(), 5);

// Print indices
for(auto i: indices)
    std::cout << i << " ";
std::cout << "\n";

// Print values corresponding to the indices
for(auto i: indices)
    std::cout << v[i] << " ";
std::cout << "\n";

结果:

8 3 9 1 2 
99 69 53 35 12