• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wzór jak oblicyc adres komórki tablicy 3D.

Object Storage Arubacloud
0 głosów
643 wizyt
pytanie zadane 20 lutego 2018 w C i C++ przez KacperO Nowicjusz (210 p.)
Jeżeli wzór żeby obliczyć adres komórki w tablicy 1D wygląda tak:

<adres początku tablicy> + <indeks wybranej komórki>

a do 2D wygląda tak:

 <adres początku tablicy> (<Y wybranej komórki> * <szerokość 1. wiersza>) + <X wybranej komórki>

to jak obliczyć adres komórki tablicy 3D? Od dłuższego czasu próbuję znaleźć odpowiedni wzór ale coś mi to nie wychodzi.
komentarz 20 lutego 2018 przez DragonCoder Nałogowiec (36,500 p.)
Mysle, ze logicznie bxloby * wysokosc komorki. Skoro w tablicy 2D masz dlugosc *szerokosc (pole powierzchni prastokatu), to wezmy wzor prostopadloscianu a*b*h. To tylko logiczny sposob podejscia do wzoru, ktory jako 1. wpadl mi do glowy. Nie wiem czy jest dobry, ale watpie bo myslalem o tym z 10sekund, wiec cos bedzie zle :D
komentarz 20 lutego 2018 przez KacperO Nowicjusz (210 p.)

Kurcze no tak średnio, ale tak czy inaczej doceniam te twoje zmarnowane 10 sekund, hehe wink

3 odpowiedzi

+1 głos
odpowiedź 20 lutego 2018 przez criss Mędrzec (172,590 p.)
wybrane 22 lutego 2018 przez KacperO
 
Najlepsza

To zależy jak została zaalokowana. Jeśli na stosie ("normalnie" tzn. np. int arr[3][4][5]), to wzór będzie wyglądał tak:

ptr = iz*sy*sx + iy*dx + ix

iz, iy, ix to szukany przez ciebie indeks w odpowiednio: 2, 1 i 0 wymiarze
sz, sy, sx to kolejne rozmiary wymiarów 2, 1 i 0
ptr wskazuje na, określony powyższymi, indeks

Przy czym za punkt odniesienia możesz uznać &arr[0][0][0]. Oczywiście analogicznie wzór będzie wyglądał dla dowolnej ilości wymiarów.

Jeśli zaalokowałeś taką tablice dynamicznie ("na stercie"), to takiego wzoru zwyczajnie nie ma, bo każdy indeks wymiaru >0 wskazuje na kolejną tablice, która może znajdować się gdziekolwiek w pamięci. Tablice wielowymiarowe na stosie są ułożone w ciągłym bloku pamięci, więc nie ma takiego problemu. Zobacz tu: https://stackoverflow.com/questions/2565039/how-are-multi-dimensional-arrays-formatted-in-memory

komentarz 20 lutego 2018 przez KacperO Nowicjusz (210 p.)
Super, dzięki Ci wielkie! Dobrze to wytłumaczyłeś :D
komentarz 20 lutego 2018 przez monika90 Pasjonat (22,940 p.)
Tylko że zachowanie jest niezdefiniowane
+1 głos
odpowiedź 20 lutego 2018 przez Arkadiusz Sikorski Pasjonat (20,160 p.)

Próbowałeś z * <rozmiar wymiaru (x,y)> + y * <rozmiar wymiaru x> +?

komentarz 20 lutego 2018 przez KacperO Nowicjusz (210 p.)

A o co chodzi z <rozmiar wymiaru (x,y)>? Bo nie do końca jestem w temacie, trzeba pomnożyć X i Y czy jak?

1
komentarz 20 lutego 2018 przez Ajver Bywalec (2,430 p.)
Wydaje mi się, że ten wzór wygląda jakoś tak:

Głębokość * (szerokość wiersza*ilość wierszy) + wzór na tablicę 2D

Czyli inaczej mówiąc:

Z*h*w + Y*w + X.

(H - wysokość)

(W - szerokość)

Mam nadzieję, że jest to czytelne ;D
1
komentarz 20 lutego 2018 przez Arkadiusz Sikorski Pasjonat (20,160 p.)

Przez rozmiar konkretnego wymiaru miałem na myśli dla 1D - długość wiersza, dla 2D - "pole" itd.

Jeśli Twój tablicowy "prostopadłościan" będzie mieć wymiary (x, y, z) = (2,3,4),

to będzie to kolejno 2, 6.

Wtedy element o współrzędnych (1,2,3) będzie w komórce o adresie 3 * 6 + 2 * 2 + 1.

(chociaż polecam sprawdzić to jeszcze)

+1 głos
odpowiedź 20 lutego 2018 przez mokrowski Mędrzec (155,460 p.)

Myślę że wyjaśnia:

#include <iostream>
#include <iomanip>

constexpr static size_t COLS = 10;
constexpr static size_t ROWS = 7;
constexpr static size_t DEPTHS = 4;

void setValue(int * table, int value, size_t dpth, size_t row, size_t col) {
    table[dpth * (COLS * ROWS) + row * COLS + col] = value;
}

int getValue(int * table, size_t dpth, size_t row, size_t col) {
    return table[dpth * (COLS * ROWS) + row * COLS + col];
}

void showTable(int * table) {
    for(auto dpth = 0U; dpth < DEPTHS; ++dpth) {
        std::cout << "Depth: " << dpth << '\n';
        for(auto row = 0U; row < ROWS; ++row) {
            for(auto col = 0U; col < COLS; ++col) {
                std::cout << std::setw(5) <<  getValue(table, dpth, row, col);
            }
            std::cout << '\n';
        }
    }
}

int main() {
    auto table = new int[COLS * ROWS * DEPTHS]{};
    setValue(table, 42, 3, 3, 3);
    showTable(table);
    delete [] table;
}

Oczywiście lepiej zrobić na tym klasę z dostępem. Chodziło jednak o wzór. 

Podobne pytania

0 głosów
1 odpowiedź 152 wizyt
pytanie zadane 15 kwietnia 2019 w C i C++ przez wz7475 Początkujący (360 p.)
0 głosów
1 odpowiedź 244 wizyt
pytanie zadane 15 maja 2017 w C i C++ przez naryans Nowicjusz (140 p.)
–3 głosów
1 odpowiedź 242 wizyt
pytanie zadane 14 maja 2020 w C i C++ przez Ania Kowalczuk Nowicjusz (120 p.)

92,555 zapytań

141,403 odpowiedzi

319,554 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...