Многомерные массивы - Это тайна??? или просто не работает?

Автор Dr_Lecter, 7 октября 2015, 00:12

0 Пользователи и 1 гость просматривают эту тему.

Dr_Lecter

Не могу разобраться с заполнением многомерного массива, Питоньяк молчит как рыба об лед, руководство тоже ясность внести не может.

Пусть у нас есть переменная массива SampleArray()
Возможно ли объявить ее как многомерный массив без границ (т.е. границы должны определиться в момент заполнения данными)?
Возможно ли внести в нее данные типа:

Sin.ПСК;152.33;cm/s
Sin.КДС;68.77;cm/s
Sin.ИС;0.55;
Sin.ПИ;0.90;
Dex.ПСК;107.86;cm/s
Dex.КДС;34.49;cm/s
Dex.ИС;0.68;
Dex.ПИ;1.32;

из строковой переменной SampleString таким образом, чтобы ";" выступило разделителем рядов, а Chr(10) разделителем строк.

И если да то как будут проиндексированы элементы массива - только по порядку (сначала первый столбец, затем второй и т.д.) или все же к ним можно обращаться по двумя осям?

Я хочу это использовать для быстрого присвоения значений переменным.
Ну с точки зрения моей логики это наиболее простой вариант, так даже PowerShell умеет не говоря об SQL или...? Или это BASIC не умеет?

Т.е. ищи значение "Dex.ПСК" в столбце А от 0 по последнего элемент, если найдешь присвой переменной B значение согласно второму столбцу этого ряда, а переменной С значение согласно третьему столбцу этого ряда.

rami

Цитата: Dr_Lecter от  6 октября 2015, 22:12Не могу разобраться с заполнением многомерного массива, Питоньяк молчит как рыба об лед, руководство тоже ясность внести не может.
Питоньяк 8-)  молчит о "тайне массивов" в целой главе Глава 4. Операции с массивами

Я бы не стал искать "быстрые" решения, а тупо бы "дал пенделя макросам, чтоб веселей шевелили копытами" методом перебора строк и извлечения нужных значений. Вам не нужны переменные и массивы как самоцель, нужно найти определённые данные и заполнить ими целевые места (поля)
Цитата: Dr_Lecter от  6 октября 2015, 22:12Т.е. ищи значение "Dex.ПСК" в столбце А от 0 по последнего элемент, если найдешь присвой переменной B значение согласно второму столбцу этого ряда, а переменной С значение согласно третьему столбцу этого ряда.
А это "торчат уши" формулы VLOOKUP из Calc ;D

Dr_Lecter

Цитата: rami от  7 октября 2015, 08:22
А это "торчат уши" формулы VLOOKUP из Calc ;D

Нет, это торчат уши моего любимого Transact-SQL  ;)

В 4-й главе Питоньяка ничего нет про многомерные массивы, за исключением того, что они есть.
И еще всякое извращение по типу Массива Массивов (это типа для людей которые не могут многомерный представить чтоли?)

Поэтому автозаполнение 2-х мерного массива из CSV структуры приходиться делать как-то так:


iRowArrayIndex = 0
For iRowArrayIndex = LBound(aDexUterineArtery()) to UBound(aDexUterineArtery())-1
ReDim aHorizontalTempArray()
aHorizontalTempArray() = Split(aDexUterineArtery(iRowArrayIndex), ";")
iColumnArrayIndex = 0
For iColumnArrayIndex = 0 to 1
TestArray(iRowArrayIndex, iColumnArrayIndex) = aHorizontalTempArray(iColumnArrayIndex)
Next iColumnArrayIndex
Next iRowArrayIndex


А вот для 3-х мерного все будет грустнее и громоздко.
А мне бы подошел 4 или 5 мерный для моих целей оптимально.

Может есть другой путь работы?

JohnSUN

Доктор, что это было?
Цитата: Dr_Lecter от  8 октября 2015, 06:21
Поэтому автозаполнение 2-х мерного массива из CSV структуры приходиться делать как-то так:
И дальше слишком многабукав
REM iRowArrayIndex = 0 - не нужен, следующий FOR все равно присвоит ему новое значение
For iRowArrayIndex = LBound(aDexUterineArtery()) to UBound(aDexUterineArtery())-1 ' Почему до предпоследнего, почему не до конца?
REM ReDim aHorizontalTempArray() - тоже не нужен, SPLIT сам определит ему размерность
aHorizontalTempArray() = Split(aDexUterineArtery(iRowArrayIndex), ";")
REM iColumnArrayIndex = 0 - Ну, зачем?!! Если это индекс цикла, то FOR ему сам присвоит все нужные значения!
For iColumnArrayIndex = 0 to 1 ' Цикл из целых двух итераций? Это ТРИ СТРОКИ кода. Два последовательных присвоения - это только две строки...
TestArray(iRowArrayIndex, iColumnArrayIndex) = aHorizontalTempArray(iColumnArrayIndex)
Next iColumnArrayIndex
Next iRowArrayIndex

Цитата: Dr_Lecter от  8 октября 2015, 06:21
А вот для 3-х мерного все будет грустнее и громоздко.
А мне бы подошел 4 или 5 мерный для моих целей оптимально.
Может есть другой путь работы?
Есть, как не есть... Много-много-многомерные массивы придуманы теоретизирующими фанатиками от лженауки кибернетики: чтобы получить ученую степень, нужно защитить научную работу. Чтобы её защитить, нужно её написать. Чтобы её написать, нужно высосать из пальца (взять с потолка, выдумать, набредить) тему работы... А это трудно в области программирования - всё что можно уже проработано первопроходцами... В реальной жизни эти много-много-... все равно отображаются в одномерную цепочку байтов памяти, не умеет компьютер хранить данные иначе. Даже хвалёный OLAP-куб - не более чем плоская двумерная таблица с дополнительными индексами по каждой из колонок...
К чему это я?.. А, да... Другой путь работы заключается в переосмыслении конечной цели и изменении алгоритма расчета. С консультациями у специалистов.
Цитата: Dr_Lecter от  8 октября 2015, 06:21
Цитата: rami от  7 октября 2015, 08:22
А это "торчат уши" формулы VLOOKUP из Calc ;D
Нет, это торчат уши моего любимого Transact-SQL  ;)
Не важно, откуда они выторчнулись, суть та же - lookup по имеющемуся значению всех (или только некоторых) сопутствующих данных. В большинстве случаев наиболее оптимальным по соотношению "(затраты на программирование и отладку + потребляемые ресурсы машины) / быстродействие алгоритма" является двоичный поиск по отсортированному массиву. Построение сбалансированных деревьев - задача нетривиальная, трудоёмкая и затратная по ресурсам...

Цитата: Dr_Lecter от  8 октября 2015, 06:21
И еще всякое извращение по типу Массива Массивов (это типа для людей которые не могут многомерный представить чтоли?)
Нет, это разумное использование типа данных Variant. Если посмотреть, например, на методы getDataArray/setDataArray, то можно понять где они используются. А если еще раз подумать, как именно данные хранятся в памяти компьютера, то станет понятен принцип хранения и обработки данных, представленных в виде "массива массивов" (и плевать, что человека-программиста учили другому)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Dr_Lecter

Я закинул кусок кода для общего понимания конструкции.

ЦитироватьREM   iRowArrayIndex = 0 - не нужен, следующий FOR все равно присвоит ему новое значение

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

ЦитироватьReDim aHorizontalTempArray() - тоже не нужен, SPLIT сам определит ему размерность

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

Да-да-да... С функциями проще, но не всегда возможно, когда в каждом цикле  задача чуть разная. А автоматическая функция с кучей условий сама сложнее чем все 10 циклов вместе.

ЦитироватьFor iColumnArrayIndex = 0 to 1

Вот здесь именно в примере 2 присвоения, но это же пример, что в конструкции измениться от "0 to 10000"

ЦитироватьМного-много-многомерные массивы придуманы теоретизирующими фанатиками от лженауки кибернетики:

Ну положим придуманы они математиками.

Допустим у нас есть два пространства S(n-размерное) и S1 (m-размерное) при условии что n > m проекция S в пространстве S1 тоже всегда будет иметь только m-размерность.

По-моему это самоочевидно, так что какая разница как хранит компьютер?
Конечно он будет хранить только в доступном ему числе измерений.

Не ясно почему это повод отказываться от использования.
Массив массивов это на самом деле это искаженное представление 2-х мерного пространства с адресацией элементов per rectum.

Вот давайте прикинем задачу:

Необходимо получить данные о пульсационном индексе в средней мозговой артерии.
Мы храним данные в 3-х мерном массива BrainVesselsValuesArray(), где ряды это параметры, строки их значения, слои это сосуды.

Я зная правила создания и адресации просто напишу: MiddleCerebralArteryPI = BrainVesselsValuesArray(3,2,4)

А как Вы поступите - массив массивов массивов? И какой длины будет запрос? А если нам нужно еще пару измерений добавить?

JohnSUN

#5
Цитата: Dr_Lecter от  8 октября 2015, 08:06По-моему это самоочевидно, так что какая разница как хранит компьютер?
Именно ему - компьютеру - предстоит выполнять всю ту писанину, что у нас кодом зовётся... И если не ставить ему задачу с учетом "особенностей его мышления", то задачу он выполнит, но ресурсов сожрёт в разы больше
Цитата: Dr_Lecter от  8 октября 2015, 08:06
Конечно он будет хранить только в доступном ему числе измерений.
Не ясно почему это повод отказываться от использования.
rami уже пытался объяснить... Это в том сообщении, где употреблялось слово "пендель"
Цитата: Dr_Lecter от  8 октября 2015, 08:06
Массив массивов это на самом деле это искаженное представление 2-х мерного пространства с адресацией элементов per rectum.
Это с чьей точки зрения? Главный (ведущий) массив типа Variant вытянут в памяти одной длинной цепочкой байт. Сплошной. Непрерывной. Чтобы перепрыгнуть к очередному элементу массива нужно только сдвинуться от начала массива на количество байт "индекс * длина типа". Значение в найденной ячейке - адрес начала такого же одномерного, сплошного, непрерывного участка памяти, устроенного точно так же, как и ведущий массив. И так далее пока память не закончится.

Цитата: Dr_Lecter от  8 октября 2015, 08:06
Необходимо получить данные о пульсационном индексе в средней мозговой артерии.
То латынью ругается, то спецтерминологией грузит...  ;D
Цитата: Dr_Lecter от  8 октября 2015, 08:06
Мы храним данные в 3-х мерном массива BrainVesselsValuesArray(), где ряды это параметры, строки их значения, слои это сосуды.
Я зная правила создания и адресации просто напишу: MiddleCerebralArteryPI = BrainVesselsValuesArray(3,2,4)
А как Вы поступите - массив массивов массивов? И какой длины будет запрос? А если нам нужно еще пару измерений добавить?
А я просто напишу MiddleCerebralArteryPI = BrainVesselsValuesArray(3)(2)(4) - с некоторых пор такой синтаксис для StarBasic'а не проблема... (вопрос насчет "какой длины будет запрос" не игнорирую, просто я его не понял - о чём спросить-то хотел?)
А вот поиск этого самого BrainVesselsValuesArray(3,2,4) в "реальном трехмерном" массиве только на первый взгляд кажется таким же простым. Перемножаем все указанные индексы между собой, множим на длину типа данных и сдвигаемся на получившееся число байт? Как бы не так! Это будет работать только на небольших массивах. Чтобы избежать риска переполнения для больших значений индексов, само умножение обвешивается кучей дополнительных проверок. В том числе и сопоставлением указанных значений индексов с текущей размерностью массива. И всё это для чего? Чтобы кодер вместо )( написал запятую?

PS. Описывая ужасы многомерных массивов, я намеренно не использовал заумных терминов типа "страничное выделение памяти", "диспетчеризация средствами ОС" и т.п. Чтобы создать массив, программа просит у системы один сплошной кусок памяти (набранный из отдельных кусочков не годится). И операционка расшибётся в лепёшку, но эту память выделит... Или расшибётся в лепёшку (к Linux'у не относится).
Одни и те же данные в сплошном трехмерном массиве и в массиве-массивов-массивов займут один и тот же объём мозгов (при условии, что и там, и там - одинаковый тип данных Variant). Но во втором случае нет необходимости в сплошном непрерывном куске. "...это самоочевидно" (с)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне