Digamos que eu tenha um vetor de números inteiros:
std::vector<int> indices;
for (int i=0; i<15; i++) indices.push_back(i);
Então eu classifico em ordem decrescente:
sort(indices.begin(), indices.end(), [](int first, int second) -> bool{return indices[first] > indices[second];})
for (int i=0; i<15; i++) printf("%i\n", indices[i]);
Isso produz o seguinte:
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
Agora, quero que os números 3, 4, 5 e 6 sejam movidos para o final e mantenha a ordem decrescente para eles (de preferência sem precisar usar sort
pela segunda vez). Ou seja, aqui está o que eu quero:
14
13
12
11
10
9
8
7
2
1
0
6
5
4
3
Como devo modificar a função de comparação do std::sort
para conseguir isso?
return indices[first] > indices[second]
Você não quer dizerreturn first < second;
?std::greater
from<functional>
pode ser usado no lugar de sua lambda. Quanto à sua pergunta, escrever um comparador mais detalhado que garanta que seus valores sejam comparados da maneira que você deseja pode ser a maneira mais fácil de fazê-lo.return first > second
.Respostas:
Sua função de comparação está incorreta, pois os valores que você obtém como
first
esecond
são os elementos dostd::vector
. Portanto, não há necessidade de usá-los como índices. Então, você precisa mudarpara
Agora, com relação ao problema que você tenta resolver ...
Você pode deixar 3, 4, 5 e 6 fora de comparação com outros elementos e ainda compará-los entre si:
Demo
fonte
Funções da biblioteca de algoritmos padrão como
iota
,sort
,find
,rotate
ecopy
iria tornar sua vida mais fácil. Seu exemplo se resume a:Resultado:
O @TedLyngmo nos comentários enfatiza que poderia / deveria ser aprimorado com:
fonte
auto b = a + 4;
está errado (se você deseja manter a consistência com o snippet anterior). Deve serauto b = a + 3;
porque no questd::rotate
você usab + 1
Solução 1
Abordagem direta com um comparador não linear .
Solução 2
Usando
std::algorithm
s (partição)!Considerações de desempenho
Pode parecer que a segunda solução é mais lenta devido à sobrecarga da partição. Provavelmente não, devido à previsão de cache e falta de ramificação nos processadores modernos.
Referência
fonte
n <= 6 && 3 <= n
no que funciona melhor para a CPU de destino, para que você não ganhe nada introduzindo os números 2 e 7, exceto uma confusão potencial - e por que usar um ponteiro para o vetor em vez de uma referência?const
diz ao leitor que a função não altera o valor? Nesse caso específico de uma linha, pode ficar claro, mas em geral não é.