Eine Reihe an Elementen mischen



  • Hallo,
    Ich habe ein paar Fragen zur Planung und Realisierung eines kleinen Projektes.

    Ich habe einen Vector von Elementen "Pool". Die Elemente stellen wiederum struct's dar. Nun soll eine zusammenhaengende Auswahl herausgenommen werden und in einen anderen Vector "Auswahl" gesteckt werden. Bspw. also Element mit Index 20 bis 35 aus "Pool". Diese herausgenommenen Elemente sollten dabei gemischt werden. Dieses Herausnehmen geschieht rel. selten.

    "Pool" sollte irgendwann durch eine Datenbank ersetzt werden, bzw. nur einen Zwischenstelle dazu darstellen. "Auswahl" soll maximal ca 200 Elemente lang sein. Die Elemente in "Auswahl" werden der Reihe nach abgearbeitet und veraendert, am Schluss sollen diese Elemente in "Pool" nun aktualisiert werden.

    Ich arbeite mit Qt, meine Probleme sollten aber doch eher allg. sein:

    1. Die Hauptfrage ist, wie mische ich hier die Elemente am elegantesten und behalte die Moeglichkeit die veraenderten Elemente im "Pool" danach wieder zu aktualisieren?

    2. Ist Vector hier fuer "Auswahl" ein geeigneter Container?

    Danke im voraus 🙂



  • Was genau meinst du mit "Mischen" - sollen die rauskopierten Elemente zufällig durcheinandergeworfen werden? Wenn ja, schau dir mal random_shuffle() an (und copy() zum rauskopieren der Werte).

    @1: Wenn du einen Bezug zu den Originaldaten behalten willst, solltest du nur Pointer (bzw. Iteratoren in die Pool-Struktur) speichern.

    @2: random_shuffle() benötigt Random Access Iteratoren, also hast du die Auswahl zwischen vector<>, deque<> und blanken Arrays (sowie eventuell qt-eigene Containerklassen).



  • Hallo,
    Danke fuer den Beitrag. Mit "mischen" meine ich die Reihenfolge der Elemente in "Pool" in eine zufaellige andere Reihenfolge im Container "Auswahl", zu bringen.

    Bezug zu den Elementen in "Pool":
    Das Problem bei der Arbeit mit Zeigern ist folgendes: einerseits moechte ich, dass Veraenderungen, der Elemente in "Auswahl" auf die entsprechenden Elemente im "Pool" uebernommen werden - also ja zu Zeigern. Andererseits, moechte ich aber nicht direkt auf den Originalen in "Pool" arbeiten; es soll nach einem Durchgang von "Auswahl", gefragt werden, ob die Aenderungen uebernommen werden sollen oder nicht - also doch keine Zeiger?

    Ich habe mir schon ueberlegt, evtl ein Array mit int anzulegen um die Positionsnummern zu 'merken'. Oder aber vllt auch direkt statt dem Vektor "Auswahl" einen assoziativen Container (etwa eine Map) zu nehmen, allderings gibt es ja dort wiederum keine Reihenfolge nach der man die Elemente durchgehen kann. Eine dritte Moeglichkeit waere einen separaten assoziativen Container mit jeweils den Wertpaaren "Position in Auswahl" und "Position in Pool" anzulegen, allerdings koennte ich dann auch gleich beim Array bleiben.

    Wie koennte man das Problem moeglichst elegant in den Griff bekommen?



  • Fabeltier schrieb:

    Hallo,
    Danke fuer den Beitrag. Mit "mischen" meine ich die Reihenfolge der Elemente in "Pool" in eine zufaellige andere Reihenfolge im Container "Auswahl", zu bringen.

    Du kopierst sie erst mit copy() (oder einer eigenen Schleife) in den Container Auswahl und mischst diesen dann per random_shuffle().

    Bezug zu den Elementen in "Pool":
    Das Problem bei der Arbeit mit Zeigern ist folgendes: einerseits moechte ich, dass Veraenderungen, der Elemente in "Auswahl" auf die entsprechenden Elemente im "Pool" uebernommen werden - also ja zu Zeigern. Andererseits, moechte ich aber nicht direkt auf den Originalen in "Pool" arbeiten; es soll nach einem Durchgang von "Auswahl", gefragt werden, ob die Aenderungen uebernommen werden sollen oder nicht - also doch keine Zeiger?

    Eine Möglichkeit wäre es, beides abzuspeichern - leg dir Auswahl als vector<pair<int,PoolElement> > an (first speichert den Index im Pool, second eine Kopie des Elements, mit dem du hantieren kannst). Zum Aktualisieren des Pools kannst du die Objekte anhand der Indizes korrekt zuordnen (wenn du dort nichts zwischendurch umgeordnet hast).



  • Danke, das hilft mir sehr weiter!!! Ich habe mir auch schon ueberlegt einen Vektor von "Pair" Elementen anzulegen, dachte aber dass es entweder zu umstaendlich waere oder es evtl sogar schon einen entsprechenden Container gebe, der genau das macht. Somit gefaellt mir dieser Ansatz sehr gut. 🙂



  • Hallo, ich habe noch eine zusaetzliche Frage, zu diesem Thema.

    Ich "mische" meine Elemente nun folgendermassen:

    std::random_shuffle(pSelection->begin(), pSelection->end());
    

    pSelection ist ein Zeiger auf einen QVector, begin() und end() liefern entsprechend positionierten Iterator. Die Funktion funktioniert soweit und mischt die Elemente von pSelection - allerdings, immer gleich! D.h. wenn ich 1,2,3,4,5 mischen lasse, bekomme ich _jedesmal_ bspw: 2,4,1,5,3.

    Wie erreiche ich mit random_shuffle() ein "zufaelliges mischen", bei dem die Reihenfolge der Elemente jedesmal anders ist? 😕



  • Entweder du schaust in der <algorithm> nach, welchen Generator random_shuffle() verwendet und initialisierst den passend (beim MSVC ist das z.B. rand(), also mußt du am Programmstart einmal srand() aufrufen) - oder du schreibst einen eigenen Zufallsgenerator und übergibst ihn als dritten Parameter an rs.



  • Wunderbar!! Danke!!! Die Initialisierung war's.

    Fuer die Kollegen mit dem gleichen Problem,
    ich mische den Vector nun folgendermassen:

    #include <QtGui> // nur fuer Qt
    #include <algorithm>
    #include <cstdlib>
    #include <ctime>
    (...)
    srand(time(0)); 
    std::random_shuffle(pSelection->begin(), pSelection->end());
    (...)
    


  • std::srand(std::time(NULL));
    

    😉 ...


Anmelden zum Antworten