Dane są dwie tablice posortowanych liczb. Liczby zapisane w tablicach mogą się powtarzać. Zadanie polega na zliczeniu ile liczb z obydwu tablic nie ma swojego odpowiednika w drugiej tablicy.
Weźmy przykładowo tablicę {1, 2, 3, 5} oraz {2, 2, 3, 4, 5}. Jedynie 2, 3, 5 mają swoje odpowiedniki w drugiej tablicy niż one same. Oznacza to, że tablice różnią się trzema elementami.
Najprostszy algorytm, które pozwoli rozwiązać to zadanie brzmi następująco: pobierz pierwszy element z tablicy 1 i wyszukaj go w tablicy 2. Jeśli istnieje to usuń go. W przeciwnym razie zwiększ licznik różnych elementów. Nie byłby to jednak najefektywniejszy algorytm, ponieważ jego złożoność wynosi O(n1n2) co dla tablic o zbliżonej długości daje złożoność kwadratową. Algorytm można zoptymalizować, ponieważ nie została wykorzystana informacja o tym, że tablice są posortowane. Wykorzystanie wyszukiwania binarnego pozwoliłoby na zmniejszenie złożoności do O(nlog(n)), ale nie jest najlepsze możliwe rozwiązanie.
Algorytm można napisać tak, aby miał złożoność liniową O(n). Algorytm rozpoczynamy od ustalenia indeksów dla każdej tablicy na 0. Następnie porównujemy elementy aktualnie wskazywane przez indeksy. Jeśli elementy są identyczne to zwiększamy obydwa indeksy. Jednak jeśli elementy są różne to zwiększamy licznik różnych elementów, a następnie zwiększamy indeks dla tablicy, która ma mniejszy element. Proces ten powtarzamy, aż w którejś tablicy nie będzie więcej elementów.
Rozpatrzmy ponownie dwie tablice {1, 2, 3, 5} oraz {2, 2, 3, 4, 5}. Kolejno zostaną wykonane następujące operacje:
Indeks 1 | Indeks 2 | Elementy | Komentarz |
---|---|---|---|
0 | 0 | 1 i 2 | Różne, zwiększamy indeks 1 i licznik różnych elementów |
1 | 0 | 2 i 2 | Identyczne, zwiększamy oba |
2 | 1 | 3 i 2 | Różne, zwiększamy indeks 2 i licznik różnych elementów |
2 | 2 | 3 i 3 | Identyczne, zwiększamy oba |
3 | 3 | 5 i 4 | Różne, zwiększamy indeks 2 i licznik różnych elementów |
3 | 4 | 5 i 5 | Identyczne, zwiększamy oba |
W tym przypadku obydwa indeksy przekraczają długości tablic równocześnie. Ostatecznie pomiędzy tablicami istnieją dokładnie 3 różne elementy.
Poniżej znajduje się przykładowa implementacja funkcji ileBrakujacychElementow(), która dla podanych dwóch tablic sprawdza ile jest różnych elementów.
Kolejne pary elementów są porównywane. Dla takich samych elementów zwiększane są oba indeksy i1 oraz i2, ale dla różnych zwiększany jest licznik brakujących elementów, a następnie odpowiedni indeks tj. tej tablicy, której element jest mniejszy. Na koniec bardzo ważne jest, aby pamiętać, że któraś tablica może wciąż posiadać elementy do sprawdzenia, więc należy je dodać jako elementy brakujące!
Do przetestowania kodu można skorzystać z poniższego fragmentu kodu, który wczytuje od użytkownika potrzebne dane, a następnie wypisuje na ekran ile jest brakujących elementów: