2016-04-29 3 views
0

Meine Aufgabe besteht darin, die Binärdarstellung einer Zahl zu durchsuchen und ein übereinstimmendes Muster einer anderen Binärdarstellung einer Zahl zu ersetzen. Wenn ich eine Übereinstimmung erhalte, wandle ich die übereinstimmenden Bits von der ersten Ganzzahl in Nullen um und gehe weiter. Zum Beispiel wäre die Nummer 469 111010101 und ich muss es mit 5 (101) übereinstimmen. Hier ist das Programm, das ich bisher geschrieben habe. Funktioniert nicht wie erwartet.Passen Sie eine Bitfolge in einer Zahl an und konvertieren Sie dann die Übereinstimmung in Nullen?

using System; 

namespace Conductors 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //this is the number I'm searching for a match in 
      int binaryTicket = 469; 
      //This is the pattern I'm trying to match (101) 
      int binaryPerforator = 5; 

      string binaryTicket01 = Convert.ToString(binaryTicket, 2); 

      bool match = true; 
      //in a 32 bit integer, position 29 is the last one I would 
      //search in, since I'm searching for the next 3 
      for (int pos = 0; pos < 29; pos++) 
      { 
       for (int j = 0; j <= 3; j++) 
       { 
        var posInBinaryTicket = pos + j; 
        var posInPerforator = j; 

        int bitInBinaryTicket = (binaryTicket & (1 << posInBinaryTicket)) >> posInBinaryTicket; 
        int bitInPerforator = (binaryPerforator & (1 << posInPerforator)) >> posInPerforator; 

        if (bitInBinaryTicket != bitInPerforator) 
        { 
         match = false; 
         break; 
        } 
        else 
        { 
         //what would be the proper bitwise operator here? 
         bitInBinaryTicket = 0; 
        } 
       } 

       Console.WriteLine(binaryTicket01); 
      } 
     } 
    } 
} 
+0

Ich würde vorschlagen, dass dies auf http://codereview.stackexchange.com/ anstelle von SO gepostet wird. Kompletter Code, der nicht wie erwartet funktioniert, wird dort besser überprüft. – Mikanikal

+0

@Mikanikal CodeReview ist für vollständigen Code, der * funktioniert *, benötigt aber Feedback für bessere/sauberere Lösungen. Es wäre geschlossen, wenn OP es auf codereview gepostet hätte. SO ist die richtige Seite für diese Frage. Es ist jedoch derzeit unklar, wie "nicht funktioniert wie erwartet" eine Million verschiedene Dinge bedeuten kann. – Rob

+0

@Rob Das war meine Absicht, wenn es nicht so (so) klingen würde. Code, der funktioniert, aber nicht wie erwartet, was bedeutet, dass er eine bessere Lösung benötigt. Mit einer klareren Frage aus dem OP werde ich also meinen Kommentar zurückziehen. – Mikanikal

Antwort

2

Nur wenige Dinge:

  1. Verwenden uint dafür. Macht die Dinge viel einfacher beim Umgang mit Binärzahlen.
  2. Sie setzen nicht wirklich etwas ein - Sie speichern einfach Informationen, weshalb Sie die gleiche Zahl so oft ausdrucken.
  3. Sie sollten die x-Zeiten Schleife, wobei x = Länge der binären Zeichenfolge (nicht nur 29). Es gibt keine Notwendigkeit für inneren Schleifen

static void Main(string[] args) 
{ 
    //this is the number I'm searching for a match in 
    uint binaryTicket = 469; 
    //This is the pattern I'm trying to match (101) 
    uint binaryPerforator = 5; 

    var numBinaryDigits = Math.Ceiling(Math.Log(binaryTicket, 2)); 
    for (var i = 0; i < numBinaryDigits; i++) 
    { 
     var perforatorShifted = binaryPerforator << i; 

     //We need to mask off the result (otherwise we fail for checking 101 -> 111) 
     //The mask will put 1s in each place the perforator is checking. 
     var perforDigits = (int)Math.Ceiling(Math.Log(perforatorShifted, 2)); 
     uint mask = (uint)Math.Pow(2, perforDigits) - 1; 

     Console.WriteLine("Ticket:\t" + GetBinary(binaryTicket)); 
     Console.WriteLine("Perfor:\t" + GetBinary(perforatorShifted)); 
     Console.WriteLine("Mask :\t" + GetBinary(mask)); 

     if ((binaryTicket & mask) == perforatorShifted) 
     { 
      Console.WriteLine("Match."); 
      //Imagine we have the case: 

      //Ticket: 
      //111010101 
      //Perforator: 
      //000000101 

      //Is a match. What binary operation can we do to 0-out the final 101? 
      //We need to AND it with 
      //111111010 

      //To get that value, we need to invert the perforatorShifted 
      //000000101 
      //XOR 
      //111111111 
      //EQUALS 
      //111111010 

      //Which would yield: 
      //111010101 
      //AND 
      //111110000 
      //Equals 
      //111010000 

      var flipped = perforatorShifted^((uint)0xFFFFFFFF); 
      binaryTicket = binaryTicket & flipped; 
     } 
    } 

    string binaryTicket01 = Convert.ToString(binaryTicket, 2); 
    Console.WriteLine(binaryTicket01); 
} 

static string GetBinary(uint v) 
{ 
    return Convert.ToString(v, 2).PadLeft(32, '0'); 
} 

Bitte den obigen Code lesen über - wenn es etwas gibt, das Sie nicht verstehen, lassen Sie mir einen Kommentar, und ich kann mit Ihnen durch sie laufen.

+0

Lösung funktioniert. Ich danke dir sehr! Ich habe meinen Kopf immer noch nicht darum herumgelegt. Ich könnte Ihr Angebot irgendwann nutzen. Ich schätze es sehr. –

+0

@TsvetanDimoff Keine Sorge. Ich habe es mit ein wenig Debugging-Code aktualisiert, so hoffentlich können Sie sehen, wie die Verschiebung funktioniert und die Binärzahlen, mit denen wir arbeiten – Rob

+0

@Rob, ich denke, du meintest 'Uint' anstelle von' Einheit'. Ich habe mich gefragt, worüber du geredet hast, LOL. – Andrew

Verwandte Themen