Arbeiten auf dem Algorithmus:Ruby-rekursiven Algorithmus Ausgabe
Given a rows x cols screen and a sentence represented by a list of non-empty words, find how many times the given sentence can be fitted on the screen.
Note:
A word cannot be split into two lines.
The order of words in the sentence must remain unchanged.
Two consecutive words in a line must be separated by a single space.
Total words in the sentence won't exceed 100.
Length of each word is greater than 0 and won't exceed 10.
1 ≤ rows, cols ≤ 20,000.
Example 1:
Input:
rows = 2, cols = 8, sentence = ["hello", "world"]
Output:
1
Explanation:
hello---
world---
The character '-' signifies an empty space on the screen.
Example 2:
Input:
rows = 3, cols = 6, sentence = ["a", "bcd", "e"]
Output:
2
Explanation:
a-bcd-
e-a---
bcd-e-
The character '-' signifies an empty space on the screen.
Example 3:
Input:
rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"]
Output:
1
Explanation:
I-had
apple
pie-I
had--
The character '-' signifies an empty space on the screen.
Hier ist mein Code:
def words_typing(sentence, rows, cols)
count_words(sentence, rows, cols, cols, 0, 0)
end
def count_words(sentence, rows, cols, remaining_space, row_num, word_idx)
return 0 if row_num == rows #keep going until out of rows, ends the recursion
word_idx = 0 if word_idx == sentence.length #reset the word back to the first
if remaining_space >= sentence[word_idx].length
if remaining_space == sentence[word_idx].length
return 1 + count_words(sentence, rows, cols, remaining_space - sentence[word_idx].length, row_num, word_idx + 1)
else #greater than 1
return 1 + count_words(sentence, rows, cols, remaining_space - sentence[word_idx].length - 1, row_num, word_idx + 1)
end
else #move to a new line, reset remaining space
return count_words(sentence, rows, cols, cols, row_num+1, word_idx)
end
end
Der Code funktioniert wie folgt. word_idx ist der Index eines Wortes im Satz-Array. Der verbleibende Platz ist anfangs die Anzahl der Spalten. Immer wenn genügend Platz für ein Wort vorhanden ist, gebe ich 1 + den Funktionsaufruf in der gleichen Zeile mit dem nächsten Wort und dem verbleibenden Platz zurück. Wenn der verbleibende Abstand> = 1 + Wortlänge ist, werde ich dafür verantwortlich sein, zwischen zwei aufeinander folgenden Wörtern ein Leerzeichen zu haben (weshalb ich die zusätzliche Bedingung habe).
Wenn word_idx länger als das Satzarray wird, wird es wie erwartet auf Null zurückgesetzt. Die rekursive Funktion wird fortgesetzt, bis row_num jetzt größer als die Anzahl der Zeilen ist, die uns im Problem zur Verfügung gestellt werden.
Dieser Code funktioniert jedoch nicht. Meine Ausgaben sind normalerweise größer als die richtige Antwort, aber konzeptionell scheint alles in Ordnung zu sein. Jeder sieht etwas falsch mit meinem Ansatz?
groß - danke. Es funktioniert jetzt für die meisten Eingaben. Bei größeren Testfällen bekomme ich jedoch einen Stack zu tief Fehler. Ich versuche herauszufinden, warum-- Ich mache nur einen rekursiven Aufruf, je nachdem, ob ein Wort richtig geschrieben werden kann oder nicht ... also ist mein Algorithmus anderswo ineffizient? – Sunny
@Sunny Sie machen einen rekursiven Aufruf für jedes passende Wort + 1 Ich denke. Also zum Beispiel # 1 (Zeilen = 3, Spalten = 6, Satz = [a, bcd, e]) = 10 Aufrufe, Beispiel # 2 (Zeilen = 4, Spalten = 5, Satz = [I, hatte, Apfel, Kuchen ]) = 11 Anrufe. Und Ruby war nicht (ich kenne den aktuellen Zustand der Ruby-Sprache nicht) sehr funktional freundlich, also sollte man nicht zu viel Rekursion benutzen. Sie können versuchen, Stack-Level zu erhöhen oder "Tail Call Optimization" zu verwenden (Sie können es einschalten) (nicht sicher, ob es in diesem Fall funktioniert). Hier ist ein schöner Link, der es erklärt http://rpanachi.com/2016/05/30/ruby-recursion-stack-size-tail-call-optimization –