[FONT=Courier New]program DimensionIndexes;[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New][COLOR=green]{$APPTYPE CONSOLE}[/COLOR][/FONT]
[FONT=Courier New][COLOR=#008000][/COLOR][/FONT]
[FONT=Courier New]uses
SysUtils;[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]type TIntArray = array of Integer;[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]function GetAbsoluteLength(dimensions : array of Integer) : integer;
var i : Integer;
begin
Result := 1;
for i := 0 to Length(dimensions) - 1 do
Result := Result * dimensions;
end;[/FONT]
[FONT=Courier New][/FONT]
[FONT=Courier New]function GetDimensionIndexes(absoluteIndex : Integer; const indicies : array of integer) : TIntArray;
var len, i, temp : Integer;
begin
SetLength(Result, Length(indicies));
len := GetAbsoluteLength(indicies);
for i:= Length(Result) - 1 downto 0 do
begin
len := len div indicies;
temp := absoluteIndex div len;
Dec(absoluteIndex, temp * len);
Result := temp;
end;
end;[/FONT]
[FONT=Courier New] var result : TIntArray;
i : Integer;
begin
result := GetDimensionIndexes(7, [4, 3]);
for i := 0 to Length(result) - 1 do writeln(result);
end.[/FONT]
Адресация в многомерных массивах
Помогите с таким вопросом: известны количество мерностей массива и известен линейный адрес (т.е. если к массиву размером AxB адресоваться координатами [x,y] то линейный адрес y*A+x). Необходимо, зная линейный адрес и длину каждой мерности, получить n-мерные координаты. Обратная задача у меня получилась, т.е. известны n-мерные координаты а функция возвращает линейный адрес. Т.е. есть матрица размером 4 стобца на 3 строки. Значит, линейный адрес элемента [3; 1] будет семь. А вот как обратно из цифры семь и размера 4x3 получить координаты [3;1] чего-то не соображу....
Arr[x,y] == x*N+y == z <- линейный адресс
а обратное действие:
х == z / N
y == z % N
где z - линейный адресс, а N - кол-во столбцов в матрице
Arr[x,y] == x*N+y == z <- линейный адресс
а обратное действие:
х == z / N
y == z % N
где z - линейный адресс, а N - кол-во столбцов в матрице[/quote]
Для 2-х мерного массива ещё понятно, желательно бы решение в общем виде (например, для 4-х мерного массива)
i = z/N;
j = z%N;
Для трехмерного массива N*M*T
формула линейного индекса для элемента [j][k](imho) :
i*M + j + k*N*M,
и для линейного индекса z
k = z /( N*M);
z1 = z - k*N*M
i = z1/N;
j = z1%N;
для 4-х мерного N*M*T*Z, линейный индекс:
i*M + j + k*N*M + l*N*M*T,
l = z /( N*M*T);
z1 = z - l*N*M*T;
k = z1 /( N*M);
z2 = z2 - k*N*M
i = z2/N;
j = z2%N;
Проверил, для трехмерного массива формула дает правильные индексы.
Спасибо всем огромное. В результате наших рассуждений родилось решение для массивов любой мерности. Вот программа на Delphi:
Пусть m[1],..,m[k] - размерности массива, тогда линейный индекс:
l = x[k] + m[k-1]*( x[k-1] + m[k-2]*( ... ) ) // м.б. индексация в обратном порядке, вопрос соглашения
Обратная задача - целочисленное деление и взятие остатка:
x[k] = l % m[k-1]
rest = l / m[k-1] - всё, что в верхних скобках