sprawdź 1 miliard numerów telefonów komórkowych pod kątem duplikatów
To pytanie z wywiadu:
Istnieje 1 miliard numerów telefonów komórkowych, które mają 11 cyfr, są one przechowywane losowo w pliku, dla przykład 12345678910, pierwsza cyfra to 1. Przejrzyj te liczby, aby zobaczyć, czy jest jeden z duplikatem, po prostu sprawdź, czy duplikat istnieje, jeśli duplikat został znaleziony, return True, or return False. dozwolone tylko 10 MB pamięci.
Oto moje rozwiązanie:
Podziel wszystkie te liczby na 1000 plików używając hash(num)%1000
, duplikaty powinny trafić do tego samego pliku.
Po hashowaniu mam 1000 małych plików, z których każdy zawiera 1 million
liczby at most
, prawda? Nie jestem tego pewien, po prostu to robię 1 billion / 1000 = 1 million
.
Następnie dla każdego pliku zbuduj tabelę hash, aby przechowywać każdą liczbę i flag
reprezentującą jej wystąpienie.
Myślę, że potrzeba 5 B
, aby przedstawić liczbę, 4 B
dla dolnego 8 digits
i 1 B
dla górnego 3 digits
; a właściwie 1 bit
wystarczy flag
, bo muszę się tylko dowiedzieć, czy duplikat istnieje, tylko ile razy. Ale jak mogę zastosować flagę 1 bit
do każdej liczby? Jestem potknięty, więc wybieram bool
być flagą, 1 B
jest zajęte.
Na koniec, każda liczba w tabeli hash przyjmie 5B<for number> + 1B<for flag> + 4B<for the next-pointer> = 10B
, a następnie każdy plik przyjmie 10M
dla tabeli hash.
To moje głupie rozwiązanie, proszę daj mi lepsze.
Dzięki.KONTYNUACJA:
Jeśli są
no duplicates
w tych 1 miliard numerów telefonów, biorąc pod uwagę jeden numer telefonu, jak sprawdzić podanyis or is not in
Te 1 miliard liczb? Użyj jak najmniej pamięci.
Wymyśliłem 2 rozwiązania,
Numer telefonu może być reprezentowany za pomocą 5B, jak powiedziałem powyżej, przeskanuj plik, odczytaj jeden numer raz, i
xor the given number with the one read from the file
, jeśli wynik to0
, to podany jest w pliku, zajmie toO(n)
czas, prawda?Partition
liczby te do2 small files
leading bit
, co oznacza, że te liczby zleading 1-bit
idą do pliku,leading 0-bit
idą do innego pliku, tymczasem policz ile liczb w każdym pliku, jeśli dana liczba spadnie do pliku 1-bitowego, a plik 1-bitowycount
jestnot full
, toagain partition
plik 1-bitowy zgodnie zsecondary leading-bit
, i sprawdź podaną liczbę rekurencyjnie; jeśli plik 1-bitowyis full
, to numer musi być w aktach, to zajmieO(logn)
czasu, prawda?
6 answers
Najszybsze rozwiązanie (również pod względem programatora:)
# Generate some 'phones'
yes 1 | perl -wne 'chomp; ++$a; print $_."$a\n";' > phones.txt
# Split phones.txt in 10MB chunks
split -C 10000000 phones.txt
# Sort each 10MB chunk with 10MB of memory
for i in x??; do sort -S 10M $i > $i.srt; echo -ne "$i.srt\0" >> merge.txt; done
# Merge the shorted chunks with 10MB of memory
sort -S 10M --files0-from=merge.txt -m > sorted.txt
# See if there is any duplicates
test -z $(uniq -d merge.txt)
Sprawdź, czy ograniczenie użycia pamięci jest spełnione z pmap $(pidof sort) na przykład:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 22:19:29
Po hashowaniu otrzymałem 1000 małych plików, z których każdy zawiera 1 co najwyżej milion liczb, prawo
Nieprawda, w skrajnym przypadku jest możliwe, że jeden plik zawiera wszystkie liczby.
Utwórz pliki na podstawie pierwszych lub ostatnich x cyfr liczb (zignoruj początkowy 1). Podczas tworzenia tych plików można faktycznie wyciąć te cyfry, ponieważ są one równe w pliku. Jest to o wiele lepsze niż hashowanie, ponieważ chociaż wszystkie liczby mogą się jeszcze skończyć w jednym pliku, teraz zakres tych liczb jest ograniczony, więc można zmieścić go do 10MB.
Każda liczba może być stłumiona prostym bitem, ponieważ jedyną potrzebną informacją jest to, czy liczba wystąpiła wcześniej. Nie musisz przechowywać liczb rzeczywistych, adres bitu jest liczbą. W 10MB możesz zapisać 80m bitów, więc będziesz potrzebował plików 1G/80M = 12,5, ale pamiętaj, że te cyfry muszą się różnić, więc faktycznie będziesz potrzebował 100 plików (x=2).
Wreszcie, ty nie trzeba tworzyć tych plików, można również skanować cały plik wiele razy. W tym przypadku możesz mieć wiele bit-map w pamięci, ponieważ jedna nie zajmuje 10MB.
Zdecydowanie sugeruję przeczytanie tej książki, zaczyna się ona od niemal identycznego przykładu: http://www.amazon.co.uk/Programming-Pearls-ACM-Press-Bentley/dp/0201657880
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 11:34:02
Nie ma potrzeby hashowania, 10M = 83886080 bitów, umieść każdą liczbę w [0, 83886080), [83886080, 83886080 * 2) ... [xx, 99999999999) (Nie bierz pod uwagę pierwszej cyfry), około 9999999999 / 83886080 = 120 plików, następnie zbuduj bit set
, zajmuje O (N) całkowicie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 12:56:02
Możesz zastosować technikę bitset. Odnoś się do tego pytania i Odpowiedzi: Znajdź liczbę całkowitą nie spośród czterech miliardów podanych
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:45:54
Pytanie podczas rozmowy kwalifikacyjnej nakłada jedynie limit na używaną pamięć, a nie na czas potrzebny na udzielenie odpowiedzi.
Rozsądne jest zatem wdrożenie tego pytania w ten sposób:
take the first number
compare it to all numbers following it
take the second number
compare it to all numbers following it
...
Przetwarzanie miliardów liczb zajmuje ogromną ilość czasu (O (n^2)), ale nie zajmuje więcej niż 10 MB miejsca w pamięci.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 12:02:05
Możesz użyć filtrów Bloom, które zawierają tablicę bitów m i używają funkcji skrótu K. Choć nie jestem pewien, ile funkcji hash może być potrzebne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-10 16:04:45