Usando C ++, e espero que a biblioteca padrão, eu queira classificar uma sequência de amostras em ordem crescente, mas também quero lembrar os índices originais das novas amostras.
Por exemplo, eu tenho um conjunto ou vetor ou matriz de amostras A : [5, 2, 1, 4, 3]
. Quero classificá-los B : [1,2,3,4,5]
, mas também quero lembrar os índices originais dos valores, para que eu possa obter outro conjunto que seria:
C : [2, 1, 4, 3, 0 ]
- que corresponde ao índice de cada elemento em 'B', no original ' UMA'.
Por exemplo, no Matlab, você pode:
[a,b]=sort([5, 8, 7])
a = 5 7 8
b = 1 3 2
Alguém pode ver uma boa maneira de fazer isso?
for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
prefiro o padrãostd::iota( idx.begin(), idx.end(), 0 );
#include <numeric>
for iota ()iota
é o algoritmo menos obviamente nomeado em toda a biblioteca padrão do C ++.Você pode classificar std :: pair em vez de apenas ints - primeiro int são dados originais, segundo int é índice original. Em seguida, forneça um comparador que classifique apenas no primeiro int. Exemplo:
Classifique a nova instância do problema usando um comparador como:
O resultado de std :: sort no v_prime, usando esse comparador, deve ser:
Você pode separar os índices caminhando pelo vetor, pegando .second de cada std :: pair.
fonte
Suponha que o vetor dado seja
Crie um novo vetor
Classifique V e, ao classificar, em vez de comparar os elementos de V, compare os elementos correspondentes de A
fonte
std::iota()
para uma inicialização mais elegent demap
Eu escrevi versão genérica de classificação de índice.
O uso é o mesmo que std :: sort, exceto por um contêiner de índice para receber índices classificados. teste:
você deve obter 2 1 0 3. para os compiladores sem suporte ao c ++ 0x, substitua a expressão lamba como um modelo de classe:
e reescreva std :: classifique como
fonte
Agora
a
contém nossos valores e seus respectivos índices no ordenados.a[i].first = value
àsi
.a[i].second = idx
na matriz inicial.fonte
Eu me deparei com essa pergunta e descobri que classificar os iteradores diretamente seria uma maneira de classificar os valores e acompanhar os índices; Não há necessidade de definir um contêiner extra de
pair
s de (valor, índice) que seja útil quando os valores forem objetos grandes; Os iteradores fornecem o acesso ao valor e ao índice:como no exemplo de uso:
agora, por exemplo, o quinto elemento menor no vetor classificado teria valor
**idx[ 5 ]
e seu índice no vetor original seriadistance( A.begin( ), *idx[ 5 ] )
ou simplesmente*idx[ 5 ] - A.begin( )
.fonte
Há outra maneira de resolver isso, usando um mapa:
Isso irá erradicar elementos não exclusivos. Se isso não for aceitável, use um multimap:
Para gerar os índices, itere sobre o mapa ou multimap:
fonte
Bela solução por @Lukasz Wiklendt! Embora no meu caso eu precisasse de algo mais genérico, modifiquei-o um pouco:
Exemplo: encontre índices classificando um vetor de seqüências por comprimento, exceto o primeiro elemento que é um manequim.
impressões:
fonte
Considere usar
std::multimap
como sugerido por @Ulrich Eckhardt. Só que o código poderia ser ainda mais simples.Dado
Para classificar o tempo médio de inserção
Para recuperar valores e índices originais
O motivo para preferir a
std::multimap
astd::map
é permitir valores iguais nos vetores originais. Observe também que, diferentemente destd::map
,operator[]
não está definido parastd::multimap
.fonte
Crie uma
std::pair
função in e classifique o par:versão genérica:
ideona
fonte
Os itens do vetor são exclusivos? Nesse caso, copie o vetor, classifique uma das cópias com STL Sort e encontre o índice de cada item no vetor original.
Se o vetor deve manipular itens duplicados, acho melhor você implementar sua própria rotina de classificação.
fonte
Bem, minha solução usa a técnica de resíduos. Podemos colocar os valores em ordem de classificação nos 2 bytes superiores e os índices dos elementos - nos 2 bytes inferiores:
Em seguida, classifique a matriz
myints
como de costume:Depois disso, você pode acessar os índices dos elementos via residuum. O código a seguir imprime os índices dos valores classificados na ordem crescente:
Obviamente, essa técnica funciona apenas para valores relativamente pequenos na matriz original
myints
(ou seja, aqueles que podem caber nos 2 bytes superiores deint
). Mas tem o benefício adicional de distinguir valores idênticos demyints
: seus índices serão impressos na ordem correta.fonte
Se for possível, você pode criar a matriz de posição usando a função find e classificar a matriz.
Ou talvez você possa usar um mapa onde a chave seria o elemento e os valores de uma lista de sua posição nas próximas matrizes (A, B e C)
Depende dos usos posteriores dessas matrizes.
fonte
Para esse tipo de pergunta Armazene os dados da matriz original em novos dados e, em seguida, procure binário no primeiro elemento da matriz classificada na matriz duplicada e esse índice deve ser armazenado em um vetor ou matriz.
Aqui binarysearch é uma função que pega a matriz, tamanho da matriz, item de pesquisa e retornaria a posição do item pesquisado
fonte
Existem muitos caminhos. Uma solução bastante simples é usar um vetor 2D.
Aqui está a saída:
fonte