(решено) Многомерный неоднородный массив, в одномерный

Модератор: Модераторы

(решено) Многомерный неоднородный массив, в одномерный

Сообщение max » 11.04.2020 22:18:29

Есть массив, например такой:
Код: Выделить всё
var
   massiv : array of array of array of byte;
   CountB : array [0..11] of byte;
   CountC : array [0..21] of byte;


заполняется примерно так:
Код: Выделить всё
for a := 0 to 10 do CountB[a] := a; // таким образом неоднородно заполняем CountB
for b := 0 to 20 do CountC[b] := b; // таким образом неоднородно заполняем CountC

// тут создаём неоднородный массив
SetLength(massiv, 11),
for a := 0 to 10 do begin
   SetLength(massiv[a], CountB[a]+1);
   for b := 0 to CountB[b] do
       SetLength(massiv[a,b], CountС[b]+1);
end;

// и как следствие получаем многомерный неоднородный массив, который потом заполняем:
for a := 0 to 10 do
    for b := 0 to CountB[a] do
        for c := 0 to CountC[b] do
            massiv[a,b,c] := c div 2;


Теперь многомерный неоднородный massiv[a,b,c] -- нужно преобразовать к одномерному массиву. Если-бы массив был-бы однородным, то это просто.
А вот, для неоднородного многомерного массива, есть-ли готовая формула перевода в одномерный массив?

PS: безусловно вариант с inc(i) -- 100% не подходит, потому что, в итоге, нужно получить доступ к значениям в одномерном массиве по тем-же вышеприведённым циклам: a, b, c.
Последний раз редактировалось max 15.04.2020 00:00:15, всего редактировалось 1 раз.
max
 

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Alex2013 » 13.04.2020 12:16:27

А что мешает просто выделить память на ВЕСЬ масив, а потом работать с дампом как угодно ?
Зы
SetLength в цикле = ДИКИЙ ТОРМОЗ ! :idea:
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение max » 13.04.2020 16:05:56

Alex2013 писал(а):выделить память на ВЕСЬ масив, а потом работать с дампом как угодно

Пример такой работы можно?
max
 

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Alex2013 » 14.04.2020 03:44:48

max писал(а):Пример такой работы можно?

Можно ...
Код: Выделить всё
Function InR(AA,B,C:Longint):Boolean;
begin
InR:=((AA>=B) And (AA<=C));
End;

// Только 24 Бита !
Procedure Set_Pixel(Var BB:TBitmap;X,Y,C:Integer);
Type
TA=Array[0..1] of byte;
var
PA:^TA;
n:integer;
begin
if bb = NIL then exit;
if not InR(x,0,bb.Width-1) then exit;
if not InR(y,0,bb.Height-1) then exit;

Bb.BeginUpdate; ;
pa:=Pointer(BB.RawImage.Data);
N:=Y*(BB.Width*3)+X*3;
pa^[n]  :=Blue(C);
pa^[n+1]:=Green(C);
pa^[n+2]:=red(C);
Bb.EndUpdate;
end;
// Только 24 Бита !
Function Get_Pixel(var BB:TBitmap;X,Y:Integer):Integer;
Type
TA=Array[0..1] of byte;
Var
PA:^TA;
  n:integer;
begin
Get_Pixel:=-1;
  if bb = NIL then exit;
  if not InR(x,0,bb.Width-1) then exit;
  if not InR(y,0,bb.Height-1) then exit;
pa:=Pointer(BB.RawImage.Data);
N:=Y*(BB.Width*3)+X*3;
Get_Pixel:=rgb(pa^[n+2],pa^[n+1],pa^[n]);
end;


Обрати внимание на Set_Pixel там четко видно как одномерный масив PA[0..Width*Height*3]
рассматривается как трехмерная матрица [0..Width-1,0..Height-1,0..2]
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение max » 14.04.2020 08:58:31

Alex2013 писал(а):Обрати внимание

Обрати внимание, в твоём примере, с решением поставленной в топике задачи -- абсолютно никакой связи нет. И судя по всему ты даже не понимаешь, суть и сложность, требуемого алгоритма, т.к. приводишь в примере двумерный массив.

Нужна формула (если такая существует), позволяющая -- многомерный (трёхмерный) неоднородный (разной длинны) массив, перевести в одномерный. И затем эта формула должна давать возможность -- получать значения из одномерного массива, по ТРЁМ значениям (a, b, c).
max
 

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Alex2013 » 14.04.2020 16:02:35

Согласен что пример не очень корректный (хотя матрица там все же трехмерная x+y+RGB ) но суть пересчета показана достаточно ясно .
"Не однородность" в простейшем случае учитывается через задание максимальных значений для всей метрики (хотя тут все зависит от конкретной задачи )

В более сложном варианте рекомендую использовать список TList (Работает в разы быстрее "array of array of array of ...")

Чуть лениво выводить общую формулу для многомерного массива но суть понятна. Для трехмерного случая есть ось Z к которой крепится множество одномерных массивов XY[Z] (разной длины) которые состоят из оси Y на которой закреплены одноименные массивы X (разной длины).

Главное, что непонятно зачем нужно знать "порядковый номер" ячейки ? ИМХО Самый простой способ просто считать количество вставок нового элемента в "связку списков" ZXY_List [Z].XY_List[Y].X_List [X] (Надеюсь работать с TList умеешь?) и запоминать в отдельной ячейке вместе со значением (и/или (в зависимости от задачи ) создать дополнительный список ссылок на значения ) .
Зы
Разумеется при любом изменении размерности "связки списков" придется все пересчитывать заново .
Последний раз редактировалось Alex2013 14.04.2020 17:56:03, всего редактировалось 4 раз(а).
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение max » 14.04.2020 16:47:02

Alex2013 писал(а):TList (Работает в разы быстрее "array of array of array of ...")

Мне не нужен TList -- мне нужен именно одномерный массив. <= это основное условие задачи.
Alex2013 писал(а):суть пересчета показана достаточно ясно

Дэ? Чтобы ты наконец-то уже понял суть задачи, вместо того чтобы флудить, пожалуйста, будь добр, при условии, например: что значения a=7, b=5, c=3 -- просто назови порядковый номер ячейки в одномерном массиве? (естественно с учётом длинны массивов указанных в начале топика). И если не сложно запиши и приложи, по порядку, все свои действия, которые будешь делать для вычисления порядкового номера. <= Хорошо? Пойми пожалуйста, это нужно только для того, чтобы ты понял суть поставленной в топике задачи. <= Если не хочешь или не способен это сделать, то ничего не пиши сюда больше. <= Договорились?
max
 

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Alex2013 » 14.04.2020 17:30:14

1 Я пытаюсь помочь .(никто кроме меня не откликнулся (задача рутинная и скучная) )
2 Какая разница как организовано сохранение массива в памяти ?
3 То же самое можно сделать и через массив .
Код: Выделить всё
Type
TR=Record
     V: byte;
     N: integer ;
end;
var
   massiv : array of array of array of TR;


Порядковий номер для a=7, b=5, c=3 можно вычислить только зная размерность каждой ветки(до указанных координат ).
ИНАЧЕ НИКАК . Поэтому проще всего считать номер при заполнении/создании массива .
В этом случае обращение massiv[7][5][3].N вернет нужный тебе номер .

Если все значения размерностей известны заранее то можно провернуть пересчет в цикле ( это как раз то что как я понимаю ты и пытался делать ) но какой-то "волшебной формулы" нет и (ИМХО) быть не может .
Последний раз редактировалось Alex2013 14.04.2020 17:47:28, всего редактировалось 2 раз(а).
Alex2013
долгожитель
 
Сообщения: 2923
Зарегистрирован: 03.04.2013 11:59:44

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Снег Север » 14.04.2020 17:46:12

max, для многомерного массива с переменным размером вложенных массивов вы никакой формулой не переведете его в одномерный, не определяя через length(...) размеры подмассивов. Alex2013 вам подсказал - сохранять номера элементов по порядку вставки во вспомогательном массиве. И более - никак это не решается.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение max » 14.04.2020 19:46:37

Alex2013 писал(а):обращение massiv[7][5][3].N вернет нужный тебе номер

О! Это реально гениальное решение, позволяющее занести порядковый номер прямо в массив -- респект!

Вот только вначале топика написано про inc(i); и сказано что inc(i); -- 100% не подходит. А приведённое решение во первых и есть inc(i), который сохраняется в массив и позволяет быстро узнать порядковый номер одномерного массива. Но зачем это нужно? Как и куда это применить? Хотя, теперь, стало возможно -- выборочно заполнять одномерный массив -- это реально круто! Но к сожалению, обратно -- это расшифровать невозможно, т.к. потребуется ещё один массив хранящий record a,b,c. И даже при создании обоих этих массивов -- поставленная задача увы не решается, т.к. в итоге, по прежнему, зная a,b,c -- невозможно получить порядковый номер, в одномерном массиве, без этого самого трёхмерного массива, который его (номер) собственно и хранит. Но как получить владея только одномерным массивом значения a,b,c или привязку к ним? Даже если передать рекорд с номерами N + номерами a,b,c в одномерный массив, то что это даст? Ну кроме того что номера массива, зачем-то ещё и продублируются в N, что это даст? Это никак не решает поставленную задачу, т.к. зная a,b,c -- невозможно получить номер в одномерном массиве, без наличия трёхмерного массива.

Alex2013 писал(а):Я пытаюсь помочь

Я не ругаюсь, как минимум тема держится в топике и её посмотрит больше людей и возможно кто-то знает решение.

Снег Север писал(а):И более - никак это не решается.

Это заведомо ложное утверждение, т.к. как минимум -- это КАК-ТО решается на аппаратном уровне. Вот как там это делается?

Снег Север писал(а):Alex2013 вам подсказал - сохранять номера элементов по порядку вставки во вспомогательном массиве

Да, Alex2013 подсказал, но сожалению -- этот способ никак не работает в одномерном массиве и лишь дублирует порядковый номер элемента, который и без того известен.
max
 

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение Снег Север » 14.04.2020 21:22:56

max писал(а):Вот как там это делается?

На аппаратном уровне это не делается никак, а на уровне ассемблера - так, как я написал, только в низкоуровневом варианте.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Многомерный неоднородный массив, перевести в одномерный

Сообщение max » 14.04.2020 21:46:02

Снег Север писал(а):на уровне ассемблера - так, как я написал

Всё. Разобрался. Действительно можно создать ещё один массив и сохранить в нём все значения и обращаться к нему силами a,b,c.
Вопрос решён.
Всем большое спасибо!
max
 

Re: (решено) Многомерный неоднородный массив, в одномерный

Сообщение java73 » 27.11.2020 12:20:09

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

Добавлено спустя 2 минуты 34 секунды:
Снег Север писал(а):
Alex2013 вам подсказал - сохранять номера элементов по порядку вставки во вспомогательном массиве

Да, Alex2013 подсказал, но сожалению -- этот способ никак не работает в одномерном массиве и лишь дублирует порядковый номер элемента, который и без того известен.

Вспомогательный массив может сохранять не номера элементов по порядку вставки, а лишь индексы для смещения после каждого подмассива
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: (решено) Многомерный неоднородный массив, в одномерный

Сообщение max » 27.11.2020 17:39:07

java73 писал(а):А можно пояснить, какова сама задача, где такая структура требуется?

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


Вернуться в Алгоритмы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru