Wprowadzenie
Wcześniej stworzyłem dwa wyzwania, w których pomysł polega na rekonstrukcji obiektu przy użyciu jak najmniejszej liczby operacji typu zapytania; to będzie trzeci.
Zadanie
Twoje dane wejściowe będą niepustym ciągiem znaków S
na alfabecie abc
i jego długości, a twój wynik będzie S
. Bez ograniczeń byłoby to oczywiście trywialne zadanie; haczykiem jest to, że nie masz S
bezpośredniego dostępu . Jedyne, co możesz zrobić, S
to wywołać funkcję num_occur(T, S)
, gdzie T
jest jakiś inny ciąg znaków i num_occur
zlicza liczbę wystąpień T
in S
. Nakładające się wystąpienia są liczone jako odrębne, więc num_occur(T, S)
naprawdę zwraca liczbę i
takich wskaźników , że
S[i, i+1, …, i+length(T)-1] == T
Na przykład num_occur("aba", "cababaababb")
wróci 3
. Zauważ też, że num_occur(S, S)
powróci 1
. Wynik num_occur("", S)
jest niezdefiniowany i nie powinieneś wywoływać funkcji na pustym ciągu.
Krótko mówiąc, powinieneś napisać funkcję lub program, który pobiera S
i length(S)
jako dane wejściowe wywołuje num_occur
niektóre krótsze ciągi znaków i S
kilka razy, rekonstruuje S
te informacje i zwraca je.
Zasady i punktacja
Twoim celem jest napisanie programu, który wykona jak najmniej wywołań num_occur
. W tym repozytorium znajdziesz plik o nazwie abc_strings.txt
. Plik zawiera 100 ciągów znaków, każdy na osobnej linii, o długości od 50 do 99. Twój wynik to łączna liczba wywołań num_occur
na tych wejściach , przy czym niższy wynik jest lepszy. Twoje rozwiązanie najlepiej będzie śledzić tę liczbę podczas jej drukowania i drukuje ją po zakończeniu. Ciągi znaków są generowane przez wybranie równomiernie losowych liter abc
; możesz optymalizować tę metodę generowania ciągów, ale nie same ciągi.
Nie ma limitu czasu, z wyjątkiem tego, że powinieneś uruchomić swoje rozwiązanie na przypadkach testowych przed jego przesłaniem. Twoje rozwiązanie powinno działać dla każdego ważnego wejścia S
, nie tylko dla przypadków testowych.
Zachęcamy również do udostępnienia swojej implementacji num_occur
, jeśli nie korzystasz z cudzej. Aby rzucić piłkę, oto implementacja w Pythonie:
def num_occur(needle, haystack):
num = 0
for i in range(len(haystack) - len(needle) + 1):
if haystack[i : i + len(needle)] == needle:
num += 1
return num
źródło
S
, czy tylko dla przypadków testowych?all non-empty strings
jakiejkolwiek długości?Odpowiedzi:
JavaScript,
1432514311 połączeńZaczynamy od pustego ciągu i idziemy rekurencyjnie, dodając nową literę na końcu lub na początku bieżącego ciągu, dopóki nadal mamy co najmniej jedno dopasowanie.
Wszystkie poprzednie wyniki z
numOccur()
są zapisywane wsym
obiekcie i używamy tych danych do natychmiastowego odrzucenia każdego nowego ciągu, który nie może być kandydatem.EDYCJA : Ponieważ zawsze zaczynamy od
'a'
, zawsze znamy dokładną liczbęa
w ciągu. Używamy tych informacji, aby zakończyć proces wcześniej, gdy wykryjemy, żea
brakuje tylko sekwencji . Naprawiono także wyrażenie regularne, które było niepoprawne w Chrome i IE.Poniżej znajduje się pełny plik wykonywalny.
Pokaż fragment kodu
źródło
Połączenia w języku Python, 15205
To przesłanie jest najprawdopodobniej nieoptymalne, ponieważ używa tylko
num_occur
do sprawdzenia, czy ciąg znaków jest podciągiemS
, i nigdy nie używa go do zliczania ilości podciągów.Algorytm działa poprzez przechowywanie łańcucha,
current
który jest zbudowany tak, aby był równyS
na końcu. Oto wszystkie kroki algorytmu:Ustalamy
current
równe''
Przejrzyj każdą literę alfabetu i wykonaj następujące czynności:
2.1 Utwórz nowy ciąg znaków
current_new
i ustaw go tak, abycurrent
następował po nim litera.2.2 Sprawdź, czy
current_new
jest uwzględnionyS
, uruchamiającnum_occur
go i sprawdź, czy wynik jest większy niż jeden.2.3 Jeśli
current_new
jest włączoneS
, zestawcurrent
docurrent_new
i wróć do kroku 2. Else, idziemy do następnego listu.Jeśli długość
current
jest równa długościS
, możemy powiedzieć, że skończyliśmy. W przeciwnym razie wracamy do kroku 2, ale modyfikujemy krok 2.1, aby byłcurrent_new
równy literze, po której następujecurrent
. Kiedy ponownie osiągniemy ten krok, jesteśmy skończeni.źródło
Połączenia w języku Python 2,
1495214754Bardzo podobny do pierwszej odpowiedzi, ale nie próbuje następnych znaków, co powoduje niemożliwe podciągi, które:
wiemy z
num_occur
tego, że nie występują w celu (z poprzednich połączeń)używaliśmy już podciągów częściej niż to wynika z
num_occur
(doda liczenie podciągów za minutę)gotoweźródło
Połączenia w języku Python
1270512632Użyłem szkieletu funkcji Loovjo. Nigdy nie piszę w Pythonie. Potrzebowałem bootrapu
EDYCJA:
Dodano kod dla ciągów o długości jednego znaku
Dodano kod, aby odrzucić już dopasowane wzorce
źródło