Podczas wywiadu na stanowisko programisty Java zapytano mnie:
Napisz funkcję, która przyjmuje dwa parametry:
- ciąg znaków reprezentujący dokument tekstowy i
- liczba całkowita podająca liczbę elementów do zwrócenia.
Zaimplementuj funkcję tak, aby zwracała listę ciągów uporządkowanych według częstotliwości słów, najczęściej występujących jako pierwsze słowo. Twoje rozwiązanie powinno działać w czasie gdzie to liczba znaków w dokumencie.
Oto, na co odpowiedziałem (w pseudokodzie), nie jest to czas a raczej czas powodu tego rodzaju. Nie mogę wymyślić, jak to zrobić czas.
wordFrequencyMap = new HashMap<String, Integer>();
words = inputString.split(' ');
for (String word : words) {
count = wordFrequencyMap.get(word);
count = (count == null) ? 1 : ++count;
wordFrequencyMap.put(word, count);
}
return wordFrequencyMap.sortByValue.keys
Czy ktoś wie lub może ktoś mi podpowiedzieć?
algorithms
sorting
strings
data-mining
użytkownik2712937
źródło
źródło
Hashtable
starsza wersja Java jest naprawdę nieistotna dla celów tej witryny.Odpowiedzi:
Proponuję wariant liczenia dystrybucji:
maxWordCound
. -maxWordCount
. Typ wpisu to listy ciągów. -Prawdopodobnie możesz zastąpić trie innymi strukturami danych w pierwszej fazie.
źródło
Zliczanie liczby wystąpień to O (n), więc sztuczka polega na znalezieniu tylko największej liczby wystąpień.
Kupa jest powszechnym sposobem agregacji najwyższych wartości k, chociaż można użyć innych metod (patrz https://en.wikipedia.org/wiki/Partial_sorting ).
Zakładając, że k jest drugim parametrem powyżej i że jest stałą w opisie problemu (wydaje się, że tak):
Ponieważ rozmiar sterty jest stały, operacje sterty są O (1), więc krok 3 to O (n).
Stertę można również utrzymywać dynamicznie podczas budowania trie.
źródło
Twój algorytm nie działa nawet w czasieO ( n logn ) ; wstawianieΘ ( n ) rzeczy w hashtable kosztują czas Ω (n2)) już (najgorszy przypadek).
To, co następuje, jest złe ; Na razie zostawiam go tutaj w celach ilustracyjnych.
Poniższy algorytm działa w najgorszym przypadkuO ( n ) (zakładając alfabet Σ o stałym rozmiarze), n liczba znaków w tekście.
Skonstruuj drzewo sufiksów tekstu, np. Za pomocą algorytmu Ukkonen .
Jeśli konstrukcja jeszcze tego nie robi, dodaj liczbę dostępnych liści do każdego (wewnętrznego) węzła.
Przejdź przez drzewo od korzenia i odetnij wszystkie gałęzie na pierwszej (białej) przestrzeni.
Przejdź przez drzewo i posortuj listę dzieci każdego węzła według liczby liści.
Wydajność drzewa (liście od lewej do prawej) jest teraz listą wszystkich słów posortowanych według częstotliwości.
Jeśli chodzi o środowisko wykonawcze:
Bardziej precyzyjne granice można uzyskać przez parametryzowanie środowiska wykonawczego liczbą różnych słów; jeśli jest ich mało, drzewo jest małe po 2.
źródło
Użyj tabeli skrótów (np.1 .. n , sortowanie według liczenia trwa O ( n ) czas. Całkowity oczekiwany czas działania wynosiO ( n ) , co jest więcej niż prawdopodobne dla wszystkich praktycznych celów (chyba że ankieter wspomniał o czymś, co zostało pominięte w twoim pytaniu). Pamiętaj, aby wspomnieć, że jest to oczekiwany czas działania, a nie najgorszy czas działania.
HashMap
), Aby zebrać wszystkie słowa i ich częstotliwości. Następnie użyj sortowania zliczającego, aby posortować słowa w kolejności malejącej częstotliwości. Ponieważ wszystkie częstotliwości są liczbami całkowitymi w zakresieTo może nie być odpowiedź, której nauczyciel szukałby w klasie algorytmów, ponieważ jest to oczekiwaneO ( n ) czas pracy zamiast O ( n ) najgorszy czas działania. Jeśli chcesz zdobyć dodatkowe punkty w pytaniu na rozmowę kwalifikacyjną, możesz od czasu do czasu wspomnieć odręcznie, że oczywiście jest to oczekiwany czas trwania, ale można to również zrobić wO ( n ) najgorszy czas działania, zastępując tabelę skrótów bardziej wyrafinowaną strukturą danych - i chętnie opracujesz sposób wyboru algorytmów w takiej sytuacji.
Lub, jeśli chcesz zagrać nieco bezpieczniej, zanim udzielisz odpowiedzi, najpierw zapytaj: „czy zależy Ci na różnicy między oczekiwanymiO ( n ) czas pracy i najgorszy przypadek O ( n ) czas trwania? ”. Następnie odpowiednio dostosuj swoją odpowiedź. Przygotuj się na to, by osoba przeprowadzająca wywiad zapytała cię, jak wybierzesz w praktyce. (Jeśli tak, zdobądź punkty!
źródło
Rozwiązanie oparte na haszcie
Nie jestem pewien, dlaczego hashtable sprawia, że złożonośćΩ (n2)) gdyby n to liczba znaków (nie słów).
Jeśli wykonujesz iterację po każdym znaku w dokumencie i podczas iteracji, oblicz kod skrótu tego słowa, przejdzieszn postacie. Oznacza to, że zaraz po napotkaniu litery zaczyna się słowo, więc zacznij obliczać skrót aż do końca słowa (istnieją specjalne przypadki interpunkcji, ale nie mają one wpływu na złożoność). Dla każdego słowa, po obliczeniu skrótu, dodaj je do tablicy skrótów. Ma to na celu uniknięcie dwukrotnego przejścia do każdego słowa, tzn. Najpierw iterację dokumentu w celu znalezienia słów, a następnie wstawienie ich do tablicy haszującej, chociaż w takim przypadku złożoność może być równieżΩ ( n ) .
Zderzenia w tablicy hashującej z pewnością stanowią problem, a w zależności od tego, jak duży był oryginalny hashtable i jak dobry jest algorytm hashujący, można zbliżyć się doO ( 1 ) do wstawiania i liczenia, a tym samym O ( n ) dla algorytmu, choć kosztem pamięci. Nadal jednak nie potrafię docenić, jak najgorszy przypadek można stwierdzićO (n2)) gdyby n to liczba znaków.
Zakłada się, że algorytm mieszający jest liniowy w czasie w stosunku do liczby znaków.
Rozwiązanie oparte na sortowaniu Radix
Alternatywnie, zakładając, że angielski, ponieważ długość słów jest dobrze znana, zamiast tego utworzę siatkę i zastosuję sortowanie radix, które jestO ( k N) gdzie k będzie maksymalną długością słowa w języku angielskim, oraz N. to łączna liczba słów. Danyn to liczba znaków w dokumencie, oraz k jest stałą, asymptotycznie to kwoty O ( n ) .
Teraz policz częstotliwość każdego słowa. Ponieważ słowa są posortowane, będziemy porównywać każde słowo z poprzednim słowem, aby sprawdzić, czy jest to to samo, czy inne. Jeśli jest taki sam, usuwamy słowo i dodajemy liczbę do poprzedniego. Jeśli jest inny, po prostu policz 1 i przejdź dalej. To wymaga2 n porównania gdzie n to liczba znaków, a zatem O ( n ) w złożoności jako całości.
Kilka najdłuższych słów w języku angielskim jest absurdalnie długie , ale potem można ograniczyć długość słowa do rozsądnej liczby (np. 30 lub mniejszej) i obciąć słowa, przyjmując margines błędu, który może z tym wynikać.
źródło