¿Hay alguna función para hacer esto?

Quiero extraer el índice 5 superior de los valores más altos en un índice.

Solo puedo obtener el índice del valor más alto, pero luego tengo que eliminarlo y volver a hacerlo, ¿algún otro método?

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);
}
2
KingAzaiez 26 jul. 2020 a las 16:04

3 respuestas

La mejor respuesta

Cree una matriz de índice y ordene parcialmente eso:

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];
                  });

Los primeros 5 elementos de indices contienen su respuesta y el vector original no está mutado.

3
wcochran 26 jul. 2020 a las 13:49

Hay varias soluciones posibles. La mayoría de las respuestas sugieren crear una copia (parcialmente) ordenada de la matriz, o de una matriz de índices. Sin embargo, eso potencialmente requiere mucho almacenamiento adicional. Si el tamaño de la entrada es muy grande, el almacenamiento adicional podría dejar de caber en la memoria caché y esto podría volverse lento.

Como alternativa, puede escanear la matriz de entrada solo una vez y mantener un conjunto de 5 índices de los elementos más grandes vistos hasta ahora. A continuación se muestra una posible implementación, que es un poco más genérica y funciona en cualquier contenedor que proporcione ForwardIterators:

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

Lo anterior probablemente podría mejorarse aún más y estar especializado para RandomAccessIterators, así que no lo haga ' Ya no es necesario tener un struct element, y solo tengo que almacenar los índices superiores n. También podría modificarse fácilmente para devolver los valores más grandes n o para devolver los iteradores a los valores más grandes n.

Ejemplo de uso:

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";

Resultado:

8 3 9 1 2 
99 69 53 35 12 
0
G. Sliepen 26 jul. 2020 a las 14:34

Enlace al código 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;
}

Lógica:

  1. Simplemente cree un vector de pares con el primer elemento de cada par como elemento de vMetric y el segundo elemento como índice de este elemento vMetric.
  2. Ahora ordene este vMetricWithIndex en orden decreciente. Tenga en cuenta que necesitamos una función auxiliar (como MyComp en el código anterior) para ordenar el vector de pares.
  3. Voila! El segundo elemento de los primeros 5 pares de vMetricWithIndex representa los índices requeridos.
0
ubaid shaikh 26 jul. 2020 a las 14:07