2012-08-02 15 views
5

To pytanie zostało mi udzielone podczas wywiadu. Wywiad jest już dawno za nami, ale ja wciąż myśli o hte problemu i jego podsłuch mnie:losowa linia w pliku

Masz język, który zawiera następujące narzędzia: a rand() funkcji, while i for pętli if oświadczeń, oraz sposobu readline() (podobne do Pythona readline()). Biorąc pod uwagę te narzędzia, napisz algorytm, który zwraca losową linię w pliku. Nie znasz rozmiaru pliku, a pętlę można przewinąć tylko raz.

+0

Czy wymagały one jednolitej dystrybucji na zwróconej linii? Bo inaczej byłoby trywialnie. – KRyan

Odpowiedz

7

nie wiem pożądaną odpowiedź, ale moje rozwiązaniem byłoby następujące:

chosen_line = "" 
lines = 0 

while (current_line = readline()): 
    if (rand(0, lines) == 0): 
     chosen_line = current_line 

    lines++ 

return chosen_line 

Edit: dobre wyjaśnienie dlaczego to działa został opublikowany w this comment.

+1

Tego właśnie szukali. Chcieli sprawdzić, czy wiesz, że produkt '(n/(n + 1))' jako 'n' idzie od' 1' do 'p' to' 1/(p + 1) '. (Dostarczone przez indukcję.) –

+7

Jeśli nie widzisz powodu, dla którego powyższy kod działa, pomyśl o tym w następujący sposób: Przyjmuje pierwszą linię z prawdopodobieństwem 1. To prawda dla jednej linii. W drugiej linii przełącza się na tę linię w połowie czasu, więc w połowie jest pierwsza linia, w połowie druga, dobra do tej pory. W trzecim wierszu zajmuje trzecią linię 1/3 czasu. Znamy połowę pozostałego czasu, jaki miał pierwszy wiersz (1/3), a połowę pozostałego czasu drugiego (1/3). Wciąż dobre dla trzech linii. I tak dalej. –

+1

@DavidSchwartz +1 Wyjaśnienie jest mile widziane. – Josh

0

Jedną z metod, zapewniając jednolitą dystrybucję:

(1) odczytać pliku wiersz po wierszu w szeregu (i podobne, np pytona list)

(2) Za pomocą rand() aby wybrać liczba od 0 do największego indeksu w tablicy.

Innym, nie gwarantuje równomierny rozkład:

przeczytać każdy wiersz. Przy każdym czytaniu również wywołaj rand(). Jeśli przekroczysz próg, zwróć linię.

+3

Downvoter: wyjaśnij, co jest nie tak z tą odpowiedzią. – Marcin

+0

Cóż, nie spadłem, ale jest wyraźnie gorszy od zaakceptowanej odpowiedzi, która dostaje jednolitą dystrybucję bez użycia tablicy. A tablice nie były jedną z cech językowych, które OP były dostępne. – jahhaj

-1

Mimo że jest podobny do trzeciej opcji Marcela, implementacja Luc zawsze zwraca pierwszą linię, parsując cały plik.

Powinno być coś takiego:

chosen_line = "" 
treshold = 90 
max = 100 

while chosen_line == "": 
    current_line = readline() 
    if (rand(0, max) > treshold): 
     chosen_line = current_line 

print chosen_line 

Można również powrócić current_line w przypadku linia nie została wybrana i przeczytać cały plik.

+2

Implementacja Luc nie zawsze zwraca pierwszą linię, a ta nie zapewnia jednorodnej dystrybucji. -1. – geoffspear

+1

Teraz rozumiem kod Luca. Nadal analizujesz cały plik, ale nie jest to opisane w problemie jako coś, czego powinieneś unikać. – gepatino

+1

Nie ma pojęcia, jak długo plik może być. Może to być pięć linii, ale także pięć milionów. Aby uzyskać dowolną losowość, musisz przeczytać cały plik, aby się dowiedzieć. Biorąc pod uwagę problemy z przepustowością, możesz ograniczyć odległość odczytu lub tak ... Ale nic w tym nie ma. – Luc