2016-05-16 9 views
2

Angenommen, wir haben eine Reihe von Binärwerten in der einige Teile auf bestimmte Buchstaben entsprechen kann, zum Beispiel:
Count möglich Dekodierungen einer bestimmten Ziffernfolge

A = 0 
B = 10 
C = 001 
D = 010 
E = 001 

Zum Beispiel, wenn wir die Zeichenfolge „001010 nehmen ", wir können 6 verschiedene Möglichkeiten haben:

AABB 
ADB 
CAB 
CD 
EAB 
ED 

Ich muss die genaue Anzahl der Kombinationen extrahieren.
Ich versuche, das Problem konzeptionell durch eine dynamische Programmierung Sicht zu lösen, aber ich habe Schwierigkeiten bei der Formulierung von Teilproblemen und in der Zusammensetzung der entsprechenden Matrix.
Ich schätze alle Hinweise auf die richtige Algorithmusformulierung.
Vielen Dank im Voraus.

+0

Ich bin ein wenig rostig bei der dynamischen Programmierung, aber ist das nicht die falsche Situation für sie? Die dynamische Programmierung zielt auf ein optimales Ergebnis ab, während Sie hier mehrere Ergebnisse erzielen. Ich glaube auch nicht, dass Sie eine Matrix verwenden können, weil A, B, C ... unterschiedliche Längen haben. – vu1p3n0x

Antwort

1

Sie können einen DP formulieren wobei f(i) = sum(f(i - j) * count(matches_j)), for all matches of length j ending at index i, die am Eingang abhängig, können Sie auch durch das Erstellen eines benutzerdefinierten trie für das Wörterbuch beschleunigen, so dass Sie nur relevante Ergebnisse (zB prüfen würde, A gefolgt von B gefolgt von D). So nehmen Sie Ihr Beispiel:

f(0) = 1 
f(1) = 1 * f(0) = 1 
f(2) = 2 
f(3) = 1 * f(2) + 1 * f(1) + 1 * f(0) = 4 
f(4) = 0 
f(5) = 1 * f(4) + 1 * f(3) + 1 * f(2) = 6 
+0

Ich versuche deine Lösung zu verstehen. Ich habe versucht, eine Matrix zu erstellen, in der die Zeilen die Teilprobleme sind (die Präfixe der Länge i) und die Spalten die Länge jeder zu testenden Kombination sind (j = 1, 2, 3); aber wenn das ein richtiger Weg ist, kann ich nicht verstehen, wie man jede Zelle [i, j] gemäß deiner Formulierung füllt. –

+0

@ JohnMòf Vielen Dank für Ihren Kommentar. Nein, mein Vorschlag ist für eine eindimensionale DP. Ich habe "j" als Zweck verwendet, um die Gruppierung des Wörterbuchs nach Länge anzugeben - in Ihrem Beispiel wäre dies "[[A], [B], [C, D, E]". Für jedes "i" im DP-Array würden Sie meiner Formel folgen. Die Reihenfolge von 'j's ist einfach die Länge des aktuellen Wörterbuchworts/s, die Sie versuchen zu entsprechen. –

+0

@ JohnMòf Zum Beispiel, bei Index '0', können Sie nur' A' ('j = 1'); während bei Index '3' können Sie' A', 'B',' D' ('j = 1 dann 2 dann 3') zuordnen. (Ich habe das Beispiel in meiner Antwort bearbeitet, nachdem ich einige Fehler bemerkt habe; sie sollten jetzt behoben werden.) –

1

Bei der Lösung von DP-Problemen hilft es oft, zuerst über eine rekursive Lösung nachzudenken und dann über eine Konvertierung in eine DP-Lösung nachzudenken.

Eine nette rekursive Erkenntnis hier ist, dass, wenn Sie eine nichtleere Ziffernfolge haben, jede Art der Dekodierung mit einem einzelnen Zeichen beginnt. Man könnte daher die Anzahl der Möglichkeiten zum Decodieren der Zeichenkette zählen, indem man jedes Zeichen ausprobiert, um zu sehen, ob es am Anfang übereinstimmt, und wenn ja, wie viele Wege es gibt, den Rest der Zeichenkette zu dekodieren.

Der Grund, warum dies zu einem schönen DP-Problem wird ist, dass wenn Sie ein einzelnes Zeichen abziehen, Sie mit einer kürzeren Folge von Ziffern bleiben, die immer ein Suffix der ursprünglichen Zeichenfolge ist. Stellen Sie sich vor, Sie hätten eine Tabelle erstellt, die für jedes Suffix der ursprünglichen Zeichenkette speichert, wie viele Möglichkeiten es gibt, diese Zeichenkette zu dekodieren. Wenn Sie diese Matrix von rechts nach links mit der obigen Erkenntnis ausfüllen, erhalten Sie schließlich die endgültige Antwort, indem Sie den Eintrag für die gesamte Zeichenfolge lesen.

Sehen Sie, wenn Sie einen Weg finden, um dies in einen konkreten Algorithmus umzuwandeln und dann zu gehen und es zu kodieren. Viel Glück!

+0

Danke. Ich versuche, das Problem mit Ihrer Sicht zu konzentrieren: Ich muss mit einem Suffix von einem Zeichen beginnen, dann betrachte ich ein Suffix von zwei Zeichen, und so weiter ..? Aber wenn ich dem Präfix einen Buchstaben hinzufüge, wie vermeide ich es, alles noch einmal zu berechnen? –

+0

Können Sie näher erläutern, was Sie mit "Hinzufügen eines Buchstabens zum Präfix" meinen? – templatetypedef

+0

Angenommen, die folgende Zeichenfolge "0010". Ich betrachte jedes Präfix: 0, 00, 001, 0010. Wenn ich das letzte (0010, die ganze Saite) betrachte, muss ich die Anzahl der Kombinationen addieren, die mit der Suffix-Zeichenfolge 001 mit der Anzahl der Kombinationen erhalten werden kann, indem man die letztes Zeichen. Ist es richtig? –

1

Sie können eine einfache rekursive Prozedur verwenden: versuchen Sie, jedes Muster an den Anfang der Zeichenfolge anzupassen; Wenn es eine Übereinstimmung gibt, wiederholen Sie rekursiv mit dem Rest der Zeichenfolge. Wenn die Zeichenfolge leer ist, haben Sie eine Decodierung gefunden.

Patterns= ["0", "10", "001", "010", "001"] 
Letters= "ABCDE" 

def Decode(In, Out): 
    global Patterns 

    if len(In) == 0: 
     print Out 
    else: 
     for i in range(len(Patterns)): 
      if In[:len(Patterns[i])] == Patterns[i]: 
       Decode(In[len(Patterns[i]):], Out + Letters[i]) 

Decode("001010", "") 

AABB 
ADB 
CAB 
CD 
EAB 
ED 
+0

Danke, interessante Lösung, aber es hat nichts mit der dynamischen Programmierung zu tun, oder? Eine reine rekursive Lösung löst das Problem wahrscheinlich nicht mehr als einmal. Und von einem Gesichtspunkt der Komplexität ..? –

+0

@ JohnMòf: Saum, du hast keine objektive Funktion, und du willst erschöpfend sein. Ich bin mir nicht sicher, ob hier Platz für dynamische Programmierung ist. –

+0

Sie haben Recht. Danke nochmal für deine Hilfe. Ihr Code funktioniert gut, es hilft mir, die optimale Lösung zu verstehen. –

Verwandte Themen