• 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.

VPS Starter Arubacloud
0 głosów
828 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 (156,260 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ź 172 wizyt
pytanie zadane 15 kwietnia 2019 w C i C++ przez wz7475 Początkujący (360 p.)
0 głosów
1 odpowiedź 337 wizyt
pytanie zadane 15 maja 2017 w C i C++ przez naryans Nowicjusz (140 p.)
–3 głosów
1 odpowiedź 276 wizyt
pytanie zadane 14 maja 2020 w C i C++ przez Ania Kowalczuk Nowicjusz (120 p.)

93,005 zapytań

141,969 odpowiedzi

321,248 komentarzy

62,341 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

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...