Tablica jest szczególnym przypadkiem zbioru danych wielowymiarowych.
Dane w zbiorze danych wielowymiarowych mogą być traktowane jako punkty w k-wymiarowej (abstrakcyjnej) przestrzeni, z którymi skojarzona jest dodatkowa informacja. Każdy z wymiarów przedstawia jakąś cechę danych. Zestaw wartości cech konkretnej danej formuje punkt k-przestrzeni, a wartość danej jest konkretną informacją skojarzoną z tym punktem.
Wielowymiarowy zbiór danych jest zatem zbiorem zestawów (K1, K2, .... Kk , I),
gdzie Ki klucz w i-m wymiarze (wartość i-ej cechy danej), I informacja (wartość samej danej).
Np. dane o dziennym utargu sieci sklepów mogą być
przedstawione jako punkty dwuwymiarowej dyskretnej przestrzeni; wymiarami
są dni i lokalizacja, a informacja skojarzona z każdym punktem określa utarg.
Lokalizacja >> Dni |
Warszawa |
Poznań |
Gdańsk |
1 lipca |
10000 |
8000 |
9000 |
2 lipca |
12000 |
7000 |
10000 |
3 lipca |
9000 |
6000 |
13000 |
Zauważmy więc, że to co ogólnie możemy traktować jako tablicę wielowymiarową, w teorii struktur danych nazywa się zbiorem danych wielowymiarowych (multidimensional data set)..
Natomiast "programistyczne" pojęcie tablicy wielowymiarowej (multidimensional array) jest tego szczególnym przypadkiem
Tablica wielowymiarowa to szczególna postać zbioru danych wielowymiarowych, mianowicie taka, w której cechy danych opisywane są przez liczby całkowite (w szczególności nieujemne).
Tablica wielowymiarowa jest zatem zbiorem zestawów (i1, i2, ... in , v),
gdzie : ik należy do zbioru Ik, Ik skończone zbiory liczb całkowitych (k =1,2..n), v wartość danej.
Zauważmy: dane w wielowymiarowej tablicy reprezentują logiczną całość (np. utarg), a zatem w językach z typami będą tego samego typu. I - co wyróżnia tablice spośród innych struktur danych dostęp do danych jest swobodny (tzn. nie wymaga uprzedniego dostępu do innych elementów zbioru).
Np. w przykładowej tablicy utargów pierwszy wymiar "dni" oznaczany jest indeksem "i" z możliwymi wartościami 0, 1, 2 oznaczającymi "1 lipca", "2 lipca", "3 lipca",. drugi wymiar "lokalizacja" indeksem j z wartościami 0,1,2 oznaczającymi "Warszawa", "Poznań", "Gdańsk". Utarg sklepu w Gdańsku z 1 lipca znajduje się w tablicy na pozycji określanej przez indeksy 0 (w wymiarze dni) i 2 (w wymiarze lokalizacji).
Mając już najogólniejszą definicję tablicy (tablica jednowymiarowa jest szczególnym przypadkiem tablicy wielowymiarowej) wypada się zastanowić czy i na ile pojęcie to zostało wdrożone w języki programowania.
Odpowiadając na to pytanie trzeba wyraźnie rozgraniczyć dwie sfery:
językową (co i w jaki sposób bezpośrednio możemy zapisać w tekście programu, czy logiczne, dotyczące dziedziny problemu, pojęcie tablicy wielowymiarowej możemy bezpośrednio odzwierciedlić w programie za pomocą środków języka?)
implementacyjną (w jaki sposób tablice są technicznie realizowane?).
Zobaczmy, jak przykładową tablicę utargów można przedstawić w języku PL/I
Np.
dcl utarg(3,3) decimal fixed(12,1); /* deklaracja tablicy */
....
do i = 1 to 3;
do j = 1 to 3;
utarg(i,j) = ...; /* odwołanie do elementu */
end;
end;
To samo możemy zrobić w Javie, za pomocą nieco innej składni
double[][] utarg = new double[3][3];
for (i=0; i < 3; i++)
for (j=0; j<3; j++)
utarg[i][j] = ...;
W języku Rexx tablica wielowymiarowa jest szczególnym przypadkiem tzw. "compound variable" (zmiennej złożonej). Możemy napisać:
utarg.1.1 = 10000
ale równie dobrze możemy napisać:
loc = "Warszawa"
day = "1 lipca"
utarg.day.loc = 10000
co jest, oczywiście, dużo bardziej sensowne i odpowiadające ogólnemu pojęciu "tablicy".
Z kolei w języku NetRexx który przejął z REXXa koncepcję pamięci asocjacyjnej - do tablicy "utarg" moglibyśmy odwołać się tak : utarg["1 lipca"]["Warszawa"].
Oczywiście, nic nie stoi na przeszkodzie (choć nie byłoby to rozsądne), by "pamiętać na boku", że "1 lipca" ma indeks i = 0, a "Warszawa" indeks j = 0 i pisać (w NetRexxie utarg[0][0] )...
W każdym ze wspomnianych języków tablice wielowymiarowe implementowane są zupełnie inaczej.
W PL/I tablica wielowymiarowa jest realizowana jako struktura danych składająca się (w przypadku dynamicznym) z deskryptora tablicy (który określa wymiary i zakresy indeksów w każdym z wymiarów) oraz samych danych ciągłej sekwencji elementów tablicy, ułożonych wierszami.
W Rexxie tablice wielowymiarowe ( i jednowymiarowa) realizowane są na zasadzie pamięci asocjacyjnej (zmienna złożona składa się z rdzenia stem i kluczy, które następują po kolejnych kropkach tail: praktycznie jest to implementowane jako odpowiednia struktura drzewiasta).
NetRexx tłumaczy swoje tablice na język Javy. M.in. przy odwołaniach asocjacyjnych na odpowiednie drzewa lub listy napisane w Javie, a jeśli tablica jest deklarowana na proste tablice Javy.
W Javie (jak w C i C++) tablica
wielowymiarowa implementowana jest jako swoista "tablica tablic".
Zatem tak naprawdę (z technicznego punktu widzena) istnieją tu tylko tablice
jednowymiarowe, a wielowymiarowość jest "symulowana" poprzez umieszczaniu
w tablicy (jako jej elementów) wskazań na inne tablice (np. wiersze tablicy
dwuwymiarowej).