Generierung einer Eindeutigen ID in c++
Was ist der beste Weg zur Erzeugung einer Eindeutigen ID, die aus zwei (oder mehr) short ints in C++? Ich versuche, eindeutig zu identifizieren vertices in einem Diagramm. Die Eckpunkte enthalten zwei bis vier short ints als Daten, und im Idealfall die ID wäre so eine Art hash von Ihnen. Lieber Portabilität und Einzigartigkeit über Geschwindigkeit oder Leichtigkeit.
Gibt es eine Menge gute Antworten hier, ich werde versuchen Sie alle heute Abend zu sehen, was passt mein problem am besten. Ein paar mehr Worte zu dem, was ich Tue.
Der graph ist eine Sammlung von Proben aus einer audio-Datei. Ich verwende den Graphen einer Markov-Kette erzeugen Sie einen neuen audio-Datei aus der alten Datei. Da jeder Knoten speichert ein paar Muster und verweist auf ein anderes Beispiel, und die samples sind alle short ints, schien es natürlich, zu generieren Sie eine ID aus den Daten. Die Kombination von Ihnen in einem langen, langen klingt gut, aber vielleicht etwas so einfaches wie nur ein 0 1 2 3 generateID
ist alles, was ich brauche. nicht sicher, wie viel Raum ist notwendig, um zu garantieren Einzigartigkeit, wenn jeder Knoten speichert 2 16 bit samples, gibt es 2^32 mögliche Kombinationen, richtig? und so, wenn jeder Knoten speichert 4 Proben, es sind 2^64 mögliche Kombinationen?
Bibliothek und Plattform-spezifische Lösungen, die nicht wirklich relevant für diese Frage. Ich möchte nicht, dass jemand, der vielleicht kompiliere mein Programm zum herunterladen zusätzlicher Bibliotheken oder ändern Sie den code entsprechend Ihrer OS.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eine einfache Lösung ist die Verwendung eines 64-bit-Ganzzahl, wo die unteren 16 bits der ersten vertex-Koordinate, die nächsten 16 bits ist die zweite, und so weiter. Diese werden einmalig für alle Ihre Scheitelpunkte, wenn auch nicht sehr kompakt.
So, hier ist etwas halbherzig-code, dies zu tun. Ich hoffe, ich habe die Modelle rechts.
Optional umgesetzt werden könnte dies mit einer union (tolle Idee von Leon Timmermans, siehe Kommentar). Sehr sauber so:
Manchmal sind die einfachsten Dinge am besten funktioniert.
Können Sie fügen Sie einfach ein id-Feld, um das Vertex-Objekt und weisen Sie ihm eine Nummer in der Reihenfolge der Konstruktion?
verwenden Sie eine lange, lange, so dass Sie können speichern Sie alle 4 Möglichkeiten, dann bitshift jeder kurz:
((long long)shortNumberX) << 0, 4, 8, oder 12
achten Sie darauf werfen bevor Sie sich, oder Ihre Daten könnten in die drop-off am Ende.
Edit: vergaß hinzuzufügen, sollten Sie ODER Sie zusammen.
Wenn Sie bevorzugen die Portabilität, dann boost::tuple ist schön:
Möchten Sie, dass ein Tupel aus 4 Elementen:
Können Sie zuordnen, wie diese:
Den boost-tuple hat bereits Unterstützung für den Vergleich, Gleichheit, etc., so ist es einfach zu bedienen, die in Containern und algorithmen.
Die definition von "ID" in der Frage ist nicht wirklich klar: Sie brauchen, um verwenden Sie es als Schlüssel für den schnellen Vertex-lookup? Definieren Sie einen Komparator für die
std::map
(siehe unten für ein Beispiel)Müssen Sie in der Lage sein, zu unterscheiden zwischen zwei Vertex-Objekte mit den gleichen Koordinaten (unterscheiden sich aber in einem anderen Bereich)? Definieren Sie hier einige id 'Fabrik' (cfr. das singleton-pattern) erzeugt z.B. eine Sequenz von Ganzzahlen, die sich nicht auf die Werte der Vertex-Objekte. - Viel in der Art Feuer Lancer schlägt (aber Vorsicht, der thread-Sicherheitsprobleme!)
Meiner Meinung nach, zwei Knoten mit identischen Koordinaten identisch sind. Also, warum würde Sie noch brauchen, eine extra ID?
Sobald Sie definieren einen 'strenge schwache bestellen' auf diese Art, Sie können verwenden Sie es als Schlüssel, z.B. eine
std::map
,Wenn Sie Windows benutzen, könnten SieCoCreateGUID API, unter Linux können Sie /proc/sys/kernel/random/uuid haben, können Sie auch einen Blick auf 'libuuid'.
Wenn Sie eine hash-Tabelle zum speichern der vertices, an die ich denken kann ein paar Möglichkeiten, um Kollisionen zu vermeiden:
Alternativ könnten Sie verwenden eine hash-Tabelle Implementierung, die Griffe Kollisionen für Sie (wie unordered_map/hash_map), und konzentrieren sich auf den rest der Anwendung.
Nun, die einzige Weise, zu garantieren, die ID eindeutig ist, ist zu machen Sie haben mehr-id-Kombinationen, als das, was Ihre gettings-ids aus
z.B. für 2 shorts (vorausgesetzt, 16-bit) verwenden, sollten Sie eine 32bit int
und für 4 shorts benötigen Sie ein 64bit int, etc...
Mit im Grunde nichts anderes Kollisionen (mehrere Dinge bekommen kann die gleichen id) sind so ziemlich garantiert.
Jedoch einen anderen Ansatz (was ich denke, wäre besser)zu bekommen-ids wäre, um Sie aus der hand als Eckpunkte eingefügt werden:
Dies hat auch den Effekt, so dass Sie hinzufügen, mehr/andere Daten an jedem vertex. Allerdings, wenn Sie erwarten, zu erstellen, die mehr als 2^32 vertices, ohne ihn, das ist wahrscheinlich nicht die beste Methode.
aus dem Stegreif würde ich sagen, verwendet Primzahlen,
Stellen Sie sicher, dass Sie nicht überlaufen Ihre id-Raum (lange? lange, lange?). Da hast du eine Feste Anzahl von Werten nur Mist einige zufällige Primzahlen. Kümmern Sie sich nicht erzeugen, gibt es genug verfügbar in den Listen, um Sie gehen für eine Weile.
Bin ich ein wenig skizzenhaft auf den Beweis, obwohl, vielleicht hat jemand mehr mathematischen kann mir Haken. Hat wahrscheinlich etwas zu tun mit der einmaligen Primzahl-ZERLEGUNG von einer Zahl.