Effizienter Algorithmus perl oder python

7

Interviewer hat in einem Interview eine Frage gestellt, um schnell & amp; effizienter Algorithmus für die untere Funktion,

Problem: Schreiben Sie eine Funktion, um eine gegebene Zeichenfolge für die unten angegebenen Regeln & amp; erzeuge die letzte analysierte Zeichenkette als Ausgabe

schreibe eine Funktion, die einen String als Eingabe akzeptiert, Stringlänge liegt zwischen [0..2000000000]

  

string sollte nur aus 'A', 'B' & amp; 'C' Zeichen wie 'AAA', 'ABCABC', 'AAAABBBBABAAACCCA'

Transformationsregeln:


1) "AB" - & gt; "AA"
2) "AC" - & gt; "AA"
3) "AA" - & gt; 'A'
4) "CC" - & gt; "C"
5) "BC" - & gt; "BB" 6) "BB" - & gt; 'B'


Übernehmen Sie alle oben genannten 6 Regeln nach dem Zufallsprinzip auf jeden gegebenen String und machen Sie den letzten transformierten String als Ausgabe

Zum Beispiel ist die Eingabe in Function: 'ABCAAB' string

ABCAAB - & gt; AACAAB [AB = AA]
AACAAB - & gt; ACAAB [AA = A]
ACAAB - & gt; AAAAB [AC = AA]
AAAAB - & gt; AAAB [AA = A]
AAAB - & gt; AAB [AA = A]
AAB - & gt; AB [AA = A]
AB - & gt; AA [AB = AA]
AA - & gt; A [AA = A]

Endergebnis: 'A'
Weil wir jetzt keine Regeln mehr auf die Zeichenfolge anwenden können.

Meine Antwort war wie (Pseudocode):

%Vor%

Kann jemand einen besseren Algorithmus vorschlagen? Ansatz für das oben genannte Problem?

    
n33rma 28.05.2015, 09:24
quelle

4 Antworten

15

Regeln 1 bis 3 werden jedes Zeichen nach einem A. verwerfen Die Regeln 5 und 6 verwerfen B und C nach einem B.
Regel 4 verwirft jedes C nach einem C. Die Reihenfolge der Substitutionen spielt keine Rolle.

Nach der Verarbeitung wird der String also C, CB, CA, CBA, B, BA, A sein.

Ein einzelner Scan der Zeichenfolge genügt. Wenn du ein C siehst, behalte es und überspringe die nächsten C's; Wenn du ein B siehst, behalte es und überspringe die nächsten B's. dann, wenn du ein A siehst, halte es und hör auf.

Das angegebene Beispiel ABCAAB liefert sofort A.

Lösungen mit expliziter Anwendung der Regeln und Mehrfachdurchgänge sind inakzeptabel, da ihr Verhalten O(N²) oder sogar O(N³) sein kann, während N=2000000000 .

    
Yves Daoust 28.05.2015 09:40
quelle
8

Sie können die Substitution wiederholen, während sie den Transformationsregeln entspricht,

%Vor%

Ausgabe

%Vor%     
Сухой27 28.05.2015 09:34
quelle
1

Hier ist eine Python-Lösung:

%Vor%     
Moj 28.05.2015 09:49
quelle
0

Die Antwort von Yves Daoust ist richtig, macht keinen Sinn, es zu simulieren. Scheint wie eine Trickfrage und das solltest du erkennen und das Verhalten verstehen und direkt umsetzen.

Yves 'Methode funktioniert, aber hier ist eine tatsächliche Implementierung eines ähnlichen:

%Vor%

Ich suche nach dem ersten 'A' und suche dann nach einem 'B' links davon (oder in der ganzen Zeichenfolge, wenn es kein 'A' gibt). Das sagt mir, ob 'B' und 'A' in die Ausgabe gehören. Für 'C' muss ich nur den Anfang der Zeichenfolge überprüfen. Während ich die gesamte Saite möglicherweise zweimal scanne, anstatt nur einmal, wie Yves es vorschlägt, macht es die find -Funktion ziemlich schnell, ungefähr 100 mal schneller, als nur die Saite "von Hand" zu durchlaufen und nur nach einem 'A' zu suchen. (was nur am Ende meines Teststrings ist):

%Vor%

Sie können dies mit nur einem Scan tun, indem Sie lstrip('C') verwenden, um das erste Nicht-C-Zeichen zu finden, und zwar schneller als von Hand, aber mit zusätzlichem Speicher und immer noch langsamer als find :

%Vor%

Reguläre Ausdrücke könnten das wahrscheinlich auch tun, aber selbst wenn ich nur nach dem 'A' suche, dauert es länger als mein ganzes transform :

%Vor%     
Stefan Pochmann 28.05.2015 14:29
quelle

Tags und Links