2016-08-01 22 views
0

Ich bin sehr neu in C, und vor allem die Bit-Manipulation Programme. Ich übte ein paar und stieß auf ein Problem namens "C-Programm zu prüfen, ob die angegebene Ganzzahl ein alternatives Muster hat". Das Folgende ist die Lösung, ich konnte nicht genau verstehen, was dieser Code macht und die Frage. Was bedeutet alternatives Muster?Programm zu prüfen, ob die angegebene Ganzzahl ein alternatives Muster

#include <stdio.h> 

void main() { 
    int num, x, y, count = 0; 

    printf("enter the number:"); 
    scanf("%d", &num); 
    x = num << 1; 
    y = x^num; 
    y = y + 1; 

    while ((y/2) != 0) { 
     if (y % 2 != 0) { 
      count++; 
      break; 
     } else { 
      y = y/2; 
     } 
    } 
    if (count) { 
     printf("false"); 
    } else { 
     printf("true"); 
    } 
} 
+3

zu produzieren Wo auch immer Sie Beispiel fanden diese erklären sollte, was ein„alternatives Muster“bedeutet. – dbush

+1

@dbush Anscheinend [es tut so etwas nicht] (http://www.sanfoundry.com/c-program-integer-alternate-pattern/). Ich gehe davon aus, dass das der OP das abrissen hat. – WhozCraig

+0

Es wurde nichts erwähnt, das erklärt, was alternative Muster sind. – Ravi

Antwort

5

„alternierendes Muster“ bedeutet ein Muster, bei dem keine zwei benachbarten Bits die gleichen sind, das heißt, wie ein Muster oder 0101010110101010.

Die Lösung hat zwei Teile:

  • erste Teil eine Zahl mit sich selbst verbindet rechts um ein Bit verschoben
  • Teil zwei verifiziert, dass das Ergebnis ist, 2 n -1

Der erste Teil verwendet den XOR-Operator ^, der nur dann eine 1 erzeugt, wenn die zwei Bits, die XOR-ed sind, verschiedene sind. Da wir eine Zahl mit sich selbst nach dem XOR-Verfahren verschieben, würde ein alternierendes Muster alle Einsen erzeugen; Jedes andere Muster würde mindestens eine Null in der Mitte erzeugen.

Teil zwei addiert eins zum Ergebnis des XOR und überprüft, ob das Ergebnis 2 n durch wiederholte Division durch zwei ist. Dies ist nicht der effizienteste Weg, es zu tun, aber a better alternative ist viel weniger intuitiv: Sie überprüfen können, dass die Anzahl und-ed mit sich selbst minus eins ist Null:

printf("enter the number:"); 
scanf("%d", &num); 
x = num >> 1; 
y = x^num; 
printf("%s\n", y & (y+1) ? "false" : "true"); 

Demo.

Hinweis: Auf 32-Bit-Systemen funktioniert diese Lösung für Nummern mit bis zu 31 Bit. Wenn der Typ mit Vorzeichen für num verwendet wird, muss der Wert nicht negativ sein.

+0

Ihr Code scheint falsch zu sein. Zum Beispiel für 2, 10, 42 und 170 drucken Sie "falsch", obwohl ihre Bitmuster "10", "1010", "101010" und "10101010" sind. Versteh ich etwas falsch? –

+0

@StefanPochmann Du hast recht, ich nahm ungerade Zahlen an; Die Lösung funktionierte nicht für gerade Zahlen. Die Lösung war einfach: Der Code muss ungerade und gerade Zahlen in verschiedene Richtungen verschieben. Bitte beachten Sie die Änderung. – dasblinkenlight

+0

Hmm, eigentlich denke ich kann man einfach * immer * shiften * richtig *, nein? –

0

Code funktioniert gut für Zahlen mit alternierendem Muster mit lsb als 1 (010101). Aber wenn lsb 0 ist (wie in 10101010), funktioniert Code nicht gut. In diesem Fall entweder Rechtsverschiebung wird bevorzugt oder zusätzliche Erhöhung ist erforderlich, alle ones.`

void main() 
    { 
     int num, x, y; 
     printf("enter the number:"); 
     scanf("%d", &num); 
     x = num << 1; 
     y = x^num; 
     y = y + 1; 
     if (!(num&1))//Additional increment if lsb is 0 to get all 1's 
      y++; 

     if (y && (!(y&y-1)))//checking power of 2 
      printf("\n%d has an alternate pattern\n",num); 
     else 
      printf("\n%d has no alternate pattern\n",num); 

    } 

`