Generiert alle Bitmuster für eine gegebene Maske

8

Mein Problem ist wie folgt: Ich habe einen Wert x und ein Muster p beide Variablen der gleichen Größe. Das Ziel besteht darin, alle Bitmuster von x zu durchlaufen, die nicht durch m maskiert sind.

Beispiel: Wenn wir p = 1001 haben, möchten wir 0000 , 0001 , 1000 und 1001 finden - nicht unbedingt in dieser Reihenfolge.

Standardimplementierung in C99 (der Rückgabewert gibt an, ob wir bereits alle Werte zurückgegeben haben):

%Vor%

Ich würde denken, dass es einen Trick geben sollte, um dies effizienter zu machen, aber ich kann keine großen Verbesserungen finden (abgesehen von der Berechnung der abschließenden Nullen der Maske und der richtigen Einstellung des Startwerts von inc, was nicht t viel von einer Verbesserung).

Edit: Wichtig ist auch die Tatsache, dass für jeden generierten Wert eine Menge zusätzlicher Arbeit generiert wird, was bedeutet, dass viele Duplikate nicht in Frage kommen (einige Duplikate, auch wenn sie nicht erkennbar sind, wären in Ordnung, es gibt keine Nebenwirkungen auf die Arbeit, es ist nur eine Verlangsamung).

    
Voo 03.02.2013, 11:33
quelle

3 Antworten

15

Dies erzeugt alle Bitmuster in umgekehrter Reihenfolge (Anfangswert von val sollte gleich mask sein):

%Vor%

Und dieser (etwas weniger offensichtliche Code) erzeugt alle Bitmuster in direkter Reihenfolge (Anfangswert von val sollte Null sein):

%Vor%     
Evgeny Kluev 03.02.2013, 11:49
quelle
1

Aus Ihrem Beispiel sieht es so aus, als würde dieser Pseudocode den Trick machen:

%Vor%

Das Generieren von C-Code von hier sollte nicht schwierig sein - ersetzen Sie bitString durch int und [pos] durch & 1 << pos oder ähnlich.

    
Dukeling 03.02.2013 11:41
quelle
0

Der optimalste Weg fühlt sich an:

  1. Zählen Sie die Anzahl der gesetzten Bits in der Maske, p
  2. Finden Sie heraus, wie Sie Bits von einem "normalisierten" binären Wert in die durch das Muster
  3. bestimmte Position mischen können
  4. Zähle durch 0..2 p -1
  5. Für jeden Wert shuffle, um einen musterkompatiblen Wert zu generieren

Dies setzt natürlich voraus, dass das Mischen relativ effizient ist, andernfalls ist es einfacher, es zu bruten, indem man einfach von 0 bis zum größten möglichen Wert zählt, abhängig von der Gesamtzahl der Bits im Muster und Anwenden des Musters bei jeder Zählung. Das Erkennen von Duplikaten ist jedoch möglicherweise etwas teuer.

Für p = 9 (binary 1001 2 ) sind nur zwei Bits gesetzt, also wissen wir, dass es 2 2 = 4 zu erzeugende Werte gibt.

Wenn wir das Muster von rechts für 1-Bit scannen, können wir die folgende "Mischtabelle" bilden:

  • Bit 0 wird von Bit 0 kopiert
  • Bit 3 wird von Bit 1
  • kopiert

Also können wir von 0 bis 3 zählen und für jeden Wert entsprechend der Tabelle neu anordnen:

  • 00 2 gibt die Ausgabe 0000 2 aus
  • 01 2 ergibt die Ausgabe 0001 2
  • 10 2 gibt die Ausgabe 1000 2 aus
  • 11 2 gibt die Ausgabe 1001 2
unwind 03.02.2013 11:39
quelle