Comment inverser une QList?

je vois qCopy et qCopybackward mais ni semble permettez-moi de faire une copie dans l'ordre inverse. qCopybackward copie seulement dans l'ordre inverse, mais garde les éléments dans le même ordre! Tout ce que je veux, c'est retourner une copie de la liste dans l'ordre inverse. Il y a a pour être une fonction pour ça, non?

24
demandé sur Daniel Brunner 2009-08-27 10:07:14
la source

7 ответов

si vous n'aimez pas le QTL, utilisez le STL. Ils n'ont peut-être pas D'API Qt-ish, mais L'API STL est stable :) cela dit, qCopyBackwardstd::copy_backward, donc au moins ils sont cohérents.

Répondre à votre question:

template <typename T>
QList<T> reversed( const QList<T> & in ) {
    QList<T> result;
    result.reserve( in.size() ); // reserve is new in Qt 4.7
    std::reverse_copy( in.begin(), in.end(), std::back_inserter( result ) );
    return result;
}

EDIT 2015-07-21: évidemment (ou peut-être pas), si vous voulez un one-liner (et les gens semblent préférer cela, en regardant les upvotes relatives de différentes réponses après cinq ans) et vous avez un non -const list ci-dessus se réduit à

std::reverse(list.begin(), list.end());

Mais je suppose que l'indice de tripoter des trucs qui est mieux pour la sécurité de l'emploi :)

28
répondu Marc Mutz - mmutz 2015-07-21 20:36:55
la source

Inverser votre QList avec une seule ligne:

for(int k = 0; k < (list.size()/2); k++) list.swap(k,list.size()-(1+k));

19
répondu Marc Jentsch 2010-11-02 17:59:39
la source

Vous pouvez utiliser le Java style itérateur. Exemple complet ici (http://doc.qt.digia.com/3.2/collection.html). Cherchez le mot "inverse".

QList<int> list; // initial list

list << 1;
list << 2;
list << 3;

QList<int> rlist; // reverse list+

QListIterator<int> it(list);
while (it.hasPrevious()) {
    rlist << it.previous();
}
9
répondu Xavier Decoret 2017-08-21 15:45:31
la source

la réponse [email protected] Jentsch est bonne. Et si vous voulez obtenir un supplément de 30% d'augmentation des performances vous pouvez changer sa doublure en:

for(int k=0, s=list.size(), max=(s/2); k<max; k++) list.swap(k,s-(1+k));

Un ThinkPad W520 avec une QList de 10 millions de QTimers j'ai obtenu ces chiffres:

  • inversion du débordement de la pile de listes a pris 194 ms
  • inversion du débordement de la pile de listes avec max et size a pris 136 ms

Le boost est une suite de

  • l'expression (liste.size()/2) étant calculée qu'une seule fois lors de l'initialisation de la boucle et non pas après chaque étape
  • la liste des expressions.size () in swap () n'est appelé qu'une fois lors de l'initialisation de la boucle et pas après chaque étape
8
répondu Robert Wloch 2013-12-18 12:19:49
la source

[Réécrire à partir de l'original]

il n'est pas clair si OP veut savoir "comment [dois-je] inverser une QList?"ou, en fait, veut une copie inverse. L'utilisateur mmutz a donné la bonne réponse pour une copie inversée, mais si vous voulez simplement inverser la liste des variables en place, il y a ceci::

#include <algorithm>

Et

std::reverse(list.begin(), list.end());

Ou en C++11:

std::reverse(std::begin(list), std::end(list));

la beauté de la bibliothèque standard C++ (et des gabarits en général) est que les algorithmes et les conteneurs sont séparé. Au début, il peut sembler ennuyeux que les conteneurs standard (et dans une moindre mesure les conteneurs Qt) n'ont pas de fonctions de commodité comme list.reverse(), mais envisager les alternatives: qui est plus élégant: fournir reverse() méthodes pour tous les conteneurs, ou définir une interface standard pour tous les conteneurs qui permettent une itération bidirectionnelle et fournissent un reverse() mise en œuvre qui fonctionne pour tous les conteneurs qui supportent l'itération bidirectionnelle?

pour illustrer pourquoi est une approche élégante, envisager les réponses à certaines des questions similaires:

"Comment faire pour renverser un std::vector<int>?":

std::reverse(std::begin(vec), std::end(vec));

"Comment faire pour renverser un std::deque<int>?":

std::reverse(std::begin(deq), std::end(deq));

Qu'parties du conteneur?

"Comment faire pour renverser les sept premiers éléments d'un et std::end fonctions, vous pouvez le faire:

"Comment inverser un tableau float x[10]?":

std::reverse(std::begin(x), std::end(x));

ou avant C++11:

std::reverse(x, x + sizeof(x) / sizeof(x[0])); 

(C'est la laideur qui std::end() se cache pour nous.)

allons-y: "Comment inverser un tampon float* x de taille n?":

std::reverse(x, x + n);

"Comment inverser une chaîne se terminant par null char* s?":

std::reverse(s, s + strlen(s));

"Comment faire pour renverser un pas-nécessairement-null-terminated string char* s dans un tampon de taille n?":

std::reverse(s, std::find(s, s + n, ''));

Notez que std::reverseswap() donc, même ceci fonctionnera à peu près aussi bien qu'il pourrait:

QList<QList<int> > bigListOfBigLists;
....
std::reverse(std::begin(bigListOfBigLists), std::end(bigListOfBigLists));

notez aussi que toutes ces boucles doivent fonctionner aussi bien qu'une boucle écrite à la main puisque, si possible, la compilateur transformera ceux-ci en arithmétique de pointeur. En outre, vous ne pouvez pas proprement écrire un réutilisable, Générique, haute performance reverse fonction comme ceci C.

7
répondu Ben 2014-06-06 16:18:33
la source

pour les listes de bibliothèques standard, cela ressemblerait à ceci

std::list<X> result;
std::copy(list.rbegin(), list.rend(), result.back_inserter());

malheureusement, Qt n'a pas les fonctions rbegin et rend qui renvoient les itérateurs inversés (ceux qui vont de l'extrémité du conteneur à son begning). Vous pouvez les écrire, ou vous pouvez simplement écrire fonction de copie sur votre propre -- inversion d'une liste est une belle excersize. Ou vous pouvez noter que QList est en fait un tableau, ce qui rend l'écriture d'une telle fonction triviale. Ou vous pouvez convertir la liste en std:: list, et utiliser rbegin et rend. Choisir ce que vous voulez.

5
répondu P Shved 2009-08-27 10:30:51
la source

Inverser une QList va être O (n) peu importe comment vous le faites, car QList n'est pas garanti d'avoir ses données stockées de façon contiguë en mémoire (contrairement à QVector). Vous pourriez considérer simplement traverser la liste dans l'ordre inverse où vous devez le faire, ou utiliser quelque chose comme un QStack qui vous permet de récupérer les éléments dans l'ordre opposé où ils ont été ajoutés.

5
répondu Colin 2010-01-15 07:10:04
la source

Autres questions sur