Отображение 2D массива на 1D массив
Я хочу представить 2D массив с 1D массивом. Функция передаст два индикатора (x,y) и значение для хранения. Эти два показателя будут представлять собой один элемент массива 1D и устанавливать его соответствующим образом. Я знаю, что 1D массив должен иметь размер arrayWidth × arrayHeight, но я не знаю, как установить каждый элемент.
например, как мне отличить (2,4,3) от (4,2,3)? Я попытался установить массив как x*y, но 2*4 и 4 * 2 приведут к тому же месту в массив и мне нужно, чтобы они были разными.
7 ответов:
вы должны решить, будут ли элементы массива храниться в порядке строк или столбцов, а затем быть последовательными. 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; }
пример: мы хотим представить 2D массив размера 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 ]; }
типичная формула для пересчета индексов 2D массива в индекс 1D массива
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) вы считаете "последним" из двух.
как другие сказали c карты в порядке строк
#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
используя основной пример строки:
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);
важно хранить данные таким образом, чтобы они могли быть получены на используемых языках. C-язык хранит в строке-главном порядке (сначала идет вся первая строка, затем вся вторая строка,...) с каждого индекса от 0 до размер-1. Таким образом, порядок массива x[2][3] равен x[0][0], x[0][1], x[0][2], x[1][0], x[1][1], x[1][2]. Таким образом, в языке C x[i][j] хранится в том же месте, что и запись 1-мерного массива x1dim[ i*3 +j]. Если данные хранятся таким образом, их легко получить в C язык.
Fortran и 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 и могут быть скорректированы соответствующим образом, чтобы получить сохраненные данные.
Извините, если это объяснение запутанно, но я думаю, что это точно и важно для программиста, чтобы знать.