Algorithmen, die berechnen, ob eine Zahl ein Vielfaches von 3 ist

13

Wenn man mentale Berechnungen macht, kann man:

  • Bei einer Ganzzahl k summieren Sie alle Ziffern (in Basis 10). Wenn das Ergebnis ein Vielfaches von 3 ist, ist k ein Vielfaches von 3.

Kennen Sie einen Algorithmus, der ähnlich arbeitet, aber mit Binärziffern (Bits) arbeitet?

  • Zuerst dachte ich daran, die vorgefertigten Funktionen meiner Sprache zu verwenden, um Integer in ASCII zu konvertieren, um die Konvertierung von Basis 2 nach Basis 10 durchzuführen, und dann den Trick der mentalen Berechnung anzuwenden. Aber natürlich könnte ich dann auch die Basisumwandlung 2 auf 10 selbst codieren. Ich habe es noch nicht getan, aber ich werde es versuchen.

  • Dann habe ich an die euklidische Division in Basis 2 gedacht ...

Ich frage mich jedoch, ob es andere Mittel gibt, Algorithmen.

Stephane Rolland
quelle
2
Vielleicht findest du es interessant: Design-DFA akzeptiert binäre Zeichenfolgen, die durch eine Zahl 'n' teilbar sind
Grijesh Chauhan

Antworten:

22

Betrachten Sie die folgenden zwei Beobachtungen (als Übung für den Leser):

  1. Die geraden Potenzen von zwei sind 1 Modulo 3.
  2. Die ungeraden Potenzen von zwei sind -1 Modulo 3.

Wir schließen daraus, dass eine Zahl (in binärer Form) nur dann durch drei teilbar ist, wenn die Summe der Bits an den geraden Stellen der Summe der Bits an den ungeraden Stellen Modulo 3 entspricht.

mhum
quelle
7
Dies ist wie die Regel, um durch 11 in Dezimalzahlen teilbar zu sein.
Yuval Filmus
1
@YuvalFilmus: Genau. Ich wollte dem Leser noch eine Übung hinzufügen, habe mich aber dagegen entschieden.
mhum
3
OK, wie wäre es, wenn Sie herausfinden, ob eine hexadezimal geschriebene Zahl durch 17 (Dezimalzahl) teilbar ist? Oder 15 (dezimal) für diese Angelegenheit? ;-)
vonbrand
33

Was ist mit einem endlichen Automaten für den Job?

Bildbeschreibung hier eingeben

Natürlich ist die Magie nur Berechnungsmodulo 3. Das Hinzufügen des Symbols hinter der Zeichenfolge x bedeutet, dass der "Binärwert" der Zeichenfolge von v a l ( x ) für x zu 2 v a l ( x ) + a für x a geht . Folglich vom Zustand p und das Symbol } und einem { 0 , 1 } . Anmerkung x { 0 , 1 }einxveinl(x)x2veinl(x)+einxeinpbewegen wir uns a zu Zustand 2 p + a mod 3 für p { 0 , 1 , 2ein2p+einmod3p{0,1,2}a{0,1} ist eine Zeichenkette, wobei v a l ( x ) N sein Wert alsBinärzeichenketteist.x{0,1}val(x)N

Hendrik Jan
quelle
1
Ich mag die Idee, lass es uns mit 9 versuchen. Ich füttere 1001 in binär. Das erste Bit schicke mich zu Zustand1, dann zu Zustand2, dann zu Zustand1 und zurück zu Zustand0. State0 ist also ein Vielfaches von 3. Und die Komplexität des Algorithmus ist die Anzahl der verwendeten Bits, nicht mehr. Es ist toll !
Stephane Rolland
Steht dieses Konzept im Zusammenhang mit dem Link? Ich denke, es ist einfacher. geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number
1
@ WaqarAhmad Ja, verwandt, nicht einfacher. Die Übergänge in einem endlichen Automaten können auch verwendet werden, um eine L2R-Auswertung zu beschreiben, wie in Ihrer Erklärung. Die Übergänge definieren , ˉ 0 1 = ˉ 1 , ˉ 1 0 = ˉ 2 , ˉ 1 1 = ˉ 0 , ˉ 2 0 = ˉ 1 , ˉ 2 1 = ˉ 20¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯. Hier haben wir drei Zustände, also sind drei Symbole für die Zustände notwendig. Ihre Symbole sind die Bewertungen der Zahlen modulo 1 , 2 , 0 , und das erste Symbol in Ihrer L2R-Bewertung ist der "Zustand". Wenn Sie eine Diskussion wünschen, ist es vielleicht besser, eine neue Frage auf der Website zu beginnen! Θ,1,01,2,0
Hendrik Jan
Mach dir keine Gedanken über Programmierung. Wird dieses Ding in einem ternären Computer effizienter sein?
4

In der Binärdarstellung ergeben die Zahlen 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100) usw. nach Division durch 11 (drei) den gleichen Rest. Wenn wir also eine Binärzahl in Teile gerader Länge aufteilen , ergibt die Summe der Teile den gleichen Rest wie die ursprüngliche Zahl.

(Wenn Sie die Zahl teilen, fügen Sie am Anfang so viele Nullen wie nötig hinzu . Beispielsweise teilen Sie 10111 in die Gruppen 01,01,11 oder 0001,0111 auf.)

Mathematisch aufgeteilt nur die Zahl in Gruppen von zwei Ziffern, fügen Sie dann die Gruppen; und wiederhole dies, bis dein Ergebnis 00 oder 11 ist = die ursprüngliche Zahl war ein Vielfaches von drei; oder 01 oder 10 = die ursprüngliche Zahl war kein Vielfaches von drei.

Bei einem Computerprogramm kann die Verwendung von Gruppen mit acht, sechzehn oder zweiunddreißig Bits für Ihre CPU schneller sein . Wenn beispielsweise die Acht-Bit-Addition am schnellsten ist, addieren Sie einfach alle Bytes und wiederholen Sie den Vorgang, bis das Ergebnis in ein Byte passt. Bestimmen Sie dann mit einer Anweisung den verbleibenden Rest, nachdem Sie durch drei geteilt haben.

(Hinweis: Wir gehen hier von vorzeichenlosen Ganzzahlen aus. Bei einer vorzeichenbehafteten Zahl muss etwas mehr darauf geachtet werden. Beispiel: 129 ist ein Vielfaches von 3, -127 jedoch nicht, obwohl die Bits 10000001 für früher als vorzeichenloses Byte und bedeuten Letzteres als vorzeichenbehaftetes Byte.)

Viliam Búr
quelle
0

Obwohl nicht binärspezifisch, ist wiederholtes Subtrahieren im Zweifel immer ein todsicherer Weg, um die Division mit dem Rest zu berechnen (und somit, wenn eine Zahl ein Vielfaches von 3 ist).

jmite
quelle
2
Wiederholte Subtraktion ist eine schlechte Idee. Die Teilung mit dem Rest ist viel schneller.
Yuval Filmus
3
wahrscheinlich wirklich sehr, sehr teuer in der CPU, aber es ist ein anderer Algorithmus :-), der nicht verdient -1 :-(
Stephane Rolland