Strona główna » Algorytmy » Wspólne Elementy Trzech Tablic
 

Wspólne Elementy Trzech Tablic

Zadanie

Dane są trzy posortowane tablice liczb całkowitych. Zadanie polega na znalezieniu wszystkich liczb, które występująca na każdej z trzech tablic. Innymi słowy należy znaleźć przecięcie trzech tablic. Zakładamy, że tablice nie mają powtarzających się elementów.

Przykładowo dla następujących tablic:

  1. 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30
  2. 3 6 9 12 15 18 21 24 27 30
  3. 4 8 12 16 20 24 28 32

Program powinien zwrócić, że powtarzającymi się elementami we wszystkich tablicach są elementy 12 oraz 24.

Rozwiązanie

Algorytm

W celu rozwiązania powyższego zadania w czasie liniowym należy zadeklarować trzy indeksy i1, i2 i i3. Po jednym dla każdej tablicy. Następnie jeśli pod wskazanymi indeksami jest ta sama wartość to wszystkie indeksy należy zwiększyć. Jeśli jednak są różne wartości to: indeks i1 zostaje zwiększony, gdy element i1 pierwszej tablicy jest mniejszy od elementu na pozycji i2 w drugiej tablicy. Analogicznie należy postąpić dla tablicy drugiej i trzeciej. Z kolei indeks trzeciej tablicy jest zwiększany, gdy nie są spełnione dwa wcześniejsze warunki. Algorytm kończy działanie, gdy k-ty indeks wykroczy poza granice k-tej tablicy.

Przykład

Dane są następujące tablice:

  1. 1 3 5 7 9 12
  2. 3 4 5 12
  3. 3 6 9 12 15

Program wykona następujące operacje:

Tablica 1Tablica 2Tablica 3Komentarz
[0]: 1[0]: 3[0]: 3El. tablicy 1 jest mniejszy od el. tablicy 2, zwiększamy indeks tablicy 1
[1]: 3[0]: 3[0]: 3Wszystkie elementy takie same, zwiększamy wszystkie indeksy i zapisujemy trafienie
[2]: 5[1]: 4[1]: 6El. tablicy 2 mniejszy od el. tablicy 3, zwiększamy indeks tablicy 2
[2]: 5[2]: 5[1]: 6Ponownie zwiększamy indeks tablicy 2
[2]: 5[3]: 12[1]: 6Zwiększamy indeks tablicy 1
[3]: 7[3]: 12[1]: 6Zwiększamy indeks tablicy 1
[4]: 9[3]: 12[1]: 6Zwiększamy indeks tablicy 1
[5]: 12[3]: 12[1]: 6Brak równości oraz zmiany indeksu tablicy 1 i 2, więc zwiększamy indeks tablicy 3
[5]: 12[3]: 12[2]: 9Zwiększamy indeks tablicy 1
[5]: 12[3]: 12[3]: 12Wszystkie elementy takie same, zwiększamy wszystkie indeksy i zapisujemy trafienie
[6]: -[4]: -[4]: 15Dla podanych indeksów wykonanie iteracji jest niemożliwe

W podanych tablicach znalezione zostały tylko dwa powtarzające się elementy: 3 oraz 12.

Implementacja

Oto przykładowa implementacja funkcji znajdzWspolneElementy(). Funkcja nie zwraca żadnej wartości, ponieważ znalezione przecięcie tablic wypisuje bezpośrednio na konsole.

  1. void znajdzWspolneElementy(int* tab1, int n1, int* tab2, int n2, int* tab3, int n3) {
  2.   int i1 = 0, i2 = 0, i3 = 0;
  3.   while (i1 < n1 && i2 < n2 && i3 < n3) {
  4.     if (tab1[i1] == tab2[i2] && tab1[i1] == tab3[i3]) {
  5.       cout << tab1[i1] << " ";
  6.       i1++;
  7.       i2++;
  8.       i3++;
  9.     } else {
  10.       if (tab1[i1] < tab2[i2]) {
  11.         i1++;
  12.       } else if (tab2[i2] < tab3[i3]) {
  13.         i2++;
  14.       } else {
  15.         i3++;
  16.       }
  17.     }
  18.   }
  19. }

(2.) Przygotuj indeksy, a następnie (3.) rozpocznij wyszukiwanie w pętli, aż w której z tablic zabraknie elementów. (4.) Jeśli zostanie znaleziony element we wszystkich tablicach to: (5.) wypisz go i (6. - 8.) zwiększ wszystkie indeksy. (9.) Jednak w przeciwnym przypadku (10. - 16.) zwiększ odpowiedni indeks.

Testowanie funkcji

Oto przykładowy kod, który wczyta od użytkownika wszystkie tablice, a następnie wywoła funkcję poszukującą przecięcia trzech tablic.

  1. int* wczytajTablice(int i, int &n) {
  2.   cout << "Podaj ile elementow ma tablice:\n n" << i << " = ";
  3.   cin >> n;
  4.   int* tab = new int[n];
  5.   for (int i = 0; i < n; i++)
  6.     cin >> tab[i];
  7.   return tab;
  8. }
  9. int main () {
  10.   int n1, n2, n3;
  11.   int* tab1 = wczytajTablice(1, n1);
  12.   int* tab2 = wczytajTablice(2, n2);
  13.   int* tab3 = wczytajTablice(3, n3);
  14.   znajdzWspolneElementy(tab1, n1, tab2, n2, tab3, n3);
  15.   system("pause");
  16.   return 0;
  17. }
Zadania
Zadanie 1
Napisz funkcję, która pozwoli na znalezienie przecięcia k tablic o różnych długościach. Przetestuj działanie napisanej funkcji.
Oto przykładowe dane wejściowe:
471 2 3 4 5 6 1571 3 5 7 9 11 1551 5 9 13 1535 10 15 20
Wynikiem są tutaj liczby 5 oraz 15.
Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1Kod źródłowy Zadanie 1