Сопоставить 2D-массив с 1D-массивом - PullRequest
77 голосов
/ 28 января 2010

Я хочу представить двумерный массив с одномерным массивом. Функция передаст две индикации (x, y) и значение для хранения. Эти два признака будут представлять один элемент одномерного массива и будут установлены соответствующим образом. Я знаю, что массив 1D должен иметь размер arrayWidth × arrayHeight, но я не знаю, как установить каждый элемент.

Например, как я могу отличить (2,4,3) от (4,2,3)? Я попытался установить массив как x * y, но 2 * 4 и 4 * 2 приведут к тому же месту в массиве, и мне нужно, чтобы они были разными.

Ответы [ 7 ]

136 голосов
/ 28 января 2010

Вам необходимо решить, будут ли элементы массива сохраняться в порядке строк или столбцов, а затем согласовываться с ними. http://en.wikipedia.org/wiki/Row-major_order

Язык C использует порядок строк для многомерных массивов

Чтобы смоделировать это с одномерным массивом, вы умножаете индекс строки на ширину и добавляете индекс столбца таким образом:

 int array[width * height];

 int SetElement(int row, int col, int value)
 {
    array[width * row + col] = value;  
 }
16 голосов
/ 28 января 2010

Типичная формула для пересчета индексов двумерных массивов в индекс одномерного массива равна

index = indexX * arrayWidth + indexY;

В качестве альтернативы вы можете использовать

index = indexY * arrayHeight + indexX;

(при условии, что arrayWidth измерено по оси X, а arrayHeight по оси Y)

Конечно, можно придумать много разных формул, которые предоставляют альтернативные уникальные отображения, но обычно в этом нет необходимости.

В языках C / C ++ встроенные многомерные массивы хранятся в памяти, поэтому последний индекс изменяется быстрее всего, что означает, что для массива, объявленного как

int xy[10][10];
За элементом

xy[5][3] сразу же следует xy[5][4] в памяти. Возможно, вы захотите следовать этому соглашению, выбрав одну из двух приведенных выше формул в зависимости от того, какой индекс (X или Y) вы считаете «последним» из двух.

15 голосов
/ 28 января 2010

Пример: мы хотим представить двумерный массив размером SIZE_X и SIZE_Y. Это означает, что у нас будет MAXY последовательных строк размера MAXX. Следовательно, установленная функция равна

void set_array( int x, int y, int val ) { array[ x * SIZE_Y + y ] = val; }

Получить будет:

int get_array( int x, int y ) { return array[ x * SIZE_Y + y ]; }
6 голосов
/ 29 октября 2015

Как и другие сказали карты С в порядке строк

   #include <stdio.h>

   int main(int argc, char **argv) {
   int i, j, k;
   int arr[5][3];
   int *arr2 = (int*)arr;

       for (k=0; k<15; k++) {
          arr2[k] = k;
          printf("arr[%d] = %2d\n", k, arr2[k]);
       }

       for (i=0; i<5; i++) {
         for (j=0; j< 3; j++) {
            printf("arr2[%d][%d] = %2d\n", i, j ,arr[i][j]);
         }
       } 
    } 

Выход:

arr[0] =  0
arr[1] =  1
arr[2] =  2
arr[3] =  3
arr[4] =  4
arr[5] =  5
arr[6] =  6
arr[7] =  7
arr[8] =  8
arr[9] =  9
arr[10] = 10
arr[11] = 11
arr[12] = 12
arr[13] = 13
arr[14] = 14
arr2[0][0] =  0
arr2[0][1] =  1
arr2[0][2] =  2
arr2[1][0] =  3
arr2[1][1] =  4
arr2[1][2] =  5
arr2[2][0] =  6
arr2[2][1] =  7
arr2[2][2] =  8
arr2[3][0] =  9
arr2[3][1] = 10
arr2[3][2] = 11
arr2[4][0] = 12
arr2[4][1] = 13
arr2[4][2] = 14
1 голос
/ 27 июля 2013

Важно хранить данные таким образом, чтобы их можно было найти на используемых языках. Язык C хранится в основном порядке строк (сначала идет вся первая строка, затем вся вторая строка ...), причем каждый индекс работает от 0 до его измерения-1. Таким образом, порядок массива x [2] [3] равен x [0] [0], x [0] [1], x [0] [2], x [1] [0], x [1] [ 1], х [1] [2]. Таким образом, в языке C x [i] [j] хранится в том же месте, что и 1-мерная запись массива x1dim [i * 3 + j]. Если данные хранятся таким образом, их легко получить на языке C.

Фортран и MATLAB разные. Они хранятся в главном порядке столбцов (сначала идет весь первый столбец, затем весь второй ряд ...), и каждый индекс проходит от 1 до своего измерения. Таким образом, порядок индексов обратен C, и все индексы на 1 больше. Если вы храните данные в порядке языка C, FORTRAN может найти X_C_language [i] [j], используя X_FORTRAN (j + 1, i + 1). Например, X_C_language [1] [2] равен X_FORTRAN (3,2). В одномерных массивах это значение данных находится в X1dim_C_language [2 * Cdim2 + 3], что соответствует позиции X1dim_FORTRAN (2 * Fdim1 + 3 + 1). Помните, что Cdim2 = Fdim1, потому что порядок индексов обратный.

MATLAB такой же, как FORTRAN. Ada такая же, как C, за исключением того, что индексы обычно начинаются с 1. Любой язык будет иметь индексы в одном из этих заказов C или FORTRAN, а индексы будут начинаться с 0 или 1 и могут быть соответствующим образом скорректированы для получения сохраненных данных.

Извините, если это объяснение сбивает с толку, но я думаю, что это точно и важно знать программисту.

1 голос
/ 28 января 2010

с использованием основного примера строки:

A(i,j) = a[i + j*ld]; // where ld is the leading dimension
                      // (commonly same as array dimension in i)

// matrix like notation using preprocessor hack, allows to hide indexing
#define A(i,j) A[(i) + (j)*ld]

double *A = ...;
size_t ld = ...;
A(i,j) = ...;
... = A(j,i);
0 голосов
/ 28 января 2010

Вы должны иметь доступ к 2d массиву с простым указателем на месте. Массив [x] [y] будет расположен в указателе как p [0x * width + 0y] [0x * width + 1y] ... [0x * width + n-1y] [1x * width + 0y] и т. Д .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...