Что нового

Двумерный, трехмерный масив

forfrends

Новичок
Сообщения
176
Репутация
3
Добрый день!
мне нужно создать два масива: двумерный, вида
Код:
$mas[$a, $b]

и трехмерный:
Код:
$mas2[$z, $x, $y]

Не могу разобраться как это сделать, точнее как к ним
Код:
DIM
приссоединить.
В формате
Код:
Dim $mas[100, 100]
Dim $mas2[100, 100, 100]

выдает ошибку при исспользовании масива:
Код:
ERROR: syntax error
				$mas[$a,
				~~~~~~~^

Помогите пожалуйста разобраться



О! решил уже:
Код:
Dim $mas[100][100]
Dim $mas2[100][100][100]

а переменную записывать как:
Код:
$mas[$a][$b]
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
forfrends [?]
а переменную записывать как:
Код:
Dim $mas[100][100]
Dim $mas2[100][100][100]

$mas[0][0] = 1
$mas[0][1] = 2
$mas[1][0] = 1
$mas[1][1] = 2
; и т.д.

$mas2[0][0][0] = 1
$mas2[0][1][0] = 2
$mas2[0][0][1] = 3
$mas2[1][0][0] = 1
$mas2[1][1][0] = 2
$mas2[1][1][1] = 3
; и т.д.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
forfrends если вы хотите задавать размерность массива с помощью переменных, то изначально вам всё равно придётся инициализировать массив с минимальной размерностью.
Код:
Dim $mas[1][1]
Dim $a = 100, $b = 100
ConsoleWrite(UBound($mas) & @CRLF) ; Начальная размерность

ReDim $mas[$a][$b] ; Меняем размерность

ConsoleWrite(UBound($mas) & @CRLF) ; Изменённая размерность
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Garrett
если мне память не изменяет, то достаточно простого
Код:
$N = 100;
$M = 50;
Dim $arr[$N][$M]

без начальной инициализации
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Это в том случае, если размерность массива известна заранее. Тогда смысла в переменных не вижу.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Garrett
Она не всегда известна заранее. Иногда приходится вычислять ее в процессе выполнения скрипта, и только потом инициализировать массив ассоциированный с этим индексом.
Код:
$N1 = 10;
$N2 = SomeFunc1($N1)
$N3 = SomeFunc2($N2)
$N4 = SomeFunc3($N3)
Dim $a[$N4]
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Вы писали:
Kaster [?]
Garrett если мне память не изменяет, то достаточно простого...без начальной инициализации

Я писал:
Garrett сказал(а):
Это в том случае, если размерность массива известна заранее. Тогда смысла в переменных не вижу.

Kaster [?]
Она не всегда известна заранее.
Об этом я и написал!

В моём примере я просто забежал немного вперёд, и предположил, что человеку заранее размерность массива не известна, поэтому у человека и возникло желание передать размерность через переменные.
Код:
#include <Array.au3>
Dim $aChar[1]
Dim $sText = "абвгдеёжзийклмн"

ReDim $aChar[StringLen($sText)] ; Меняем размерность

For $i = 0 To UBound($aChar)-1
	$aChar[$i] = StringMid($sText, $i+1, 1)
Next

_ArrayDisplay($aChar)

$sText = "12345"

ReDim $aChar[StringLen($sText)] ; Меняем размерность

For $i = 0 To UBound($aChar)-1
	$aChar[$i] = StringMid($sText, $i+1, 1)
Next

_ArrayDisplay($aChar)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Garrett
ок. зайдем по другому. вот твой же скрипт, но без начальной инициализации
Код:
#include <Array.au3>
Dim $sText = "абвгдеёжзийклмн"

Dim $aChar[StringLen($sText)] ;

For $i = 0 To UBound($aChar)-1
    $aChar[$i] = StringMid($sText, $i+1, 1)
Next

_ArrayDisplay($aChar)

$sText = "12345"

Dim $aChar[StringLen($sText)] ; Меняем размерность

For $i = 0 To UBound($aChar)-1
    $aChar[$i] = StringMid($sText, $i+1, 1)
Next

_ArrayDisplay($aChar)
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Kaster [?]
но без начальной инициализации
В этом примере она у вас дважды. Вы дважды объявляете массив.
ReDim специально для того, чтобы менять размерность уже созданного массива.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Garrett
смысл был в другом - как объявлять массивы. который можно передать на все том же примере, если не нравится двойное объявление
Код:
#include <Array.au3>
Dim $sText = "абвгдеёжзийклмн"

Dim $aChar[StringLen($sText)] ;

For $i = 0 To UBound($aChar)-1
    $aChar[$i] = StringMid($sText, $i+1, 1)
Next

_ArrayDisplay($aChar)

я все еще в упор не вижу, зачем создавать массив размерности 1х1
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Может быть не совсем в тему, но хочу сказать про скорость обработки массивов. Я раньше, если есть условие добавления элемента в массив, сначала создавал массив 1х1, потом, если условие соблюдается, изменял его размерность и добавлял новый элемент:
Код:
#include <Array.au3>

Dim $sText = ''
$iChr = 224

For $i = 1 To 10000
	$sText &= Chr($iChr)
	$iChr += 1
	If $iChr = 256 Then $iChr = 224
Next
$iStart = TimerInit()
$j = 0
Dim $aChar[$j + 1]

For $i = 0 To StringLen($sText) - 1
	$sTemp = StringMid($sText, $i + 1, 1)
	If $sTemp <> 'й' Then
		$j += 1
		ReDim $aChar[$j + 1]
		$aChar[$j] = $sTemp
	EndIf
Next
$aChar[0] = $j
$sEnd = StringFormat('%.2f sec', TimerDiff($iStart) / 1000)
_ArrayDisplay($aChar, $sEnd)
С большим объемом данных делается это очень долго.
Некоторое время назад эта тема у нас на форуме обсуждалась, сейчас, к сожалению, не помню где. После изучения этой темы стал делать так:
Код:
#include <Array.au3>

Dim $sText = ''
$iChr = 224

For $i = 1 To 10000
	$sText &= Chr($iChr)
	$iChr += 1
	If $iChr = 256 Then $iChr = 224
Next
$iStart = TimerInit()
Dim $aChar[StringLen($sText) + 1]
$j = 0
For $i = 0 To UBound($aChar) - 1
	$sTemp = StringMid($sText, $i + 1, 1)
	If $sTemp <> 'й' Then
		$j += 1
		$aChar[$j] = $sTemp
	EndIf
Next
ReDim $aChar[$j]
$aChar[0] = $j - 1
$sEnd = StringFormat('%.2f sec', TimerDiff($iStart) / 1000)
_ArrayDisplay($aChar, $sEnd)
Скорость обработки увеличилась во много раз. :IL_AutoIt_1:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Kaster [?]
зачем создавать массив размерности 1х1
Я считаю так грамотнее. Вы считаете не нужно? Ваше право!

Скажите, нужно в этом случае использовать Eval ?
Код:
If Assign("variable", "Hello", 2) Then MsgBox(4096, "", $variable)


P.S. Многие люди не моют руки перед едой, и как не странно они не болеют дизентерией. Может на самом деле, не стоит их мыть?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Garrett [?]
Я считаю так грамотнее. Вы считаете не нужно? Ваше право!
ок. теперь это просто грамотнее, уже лучше. а то вначале было, что это просто необходимо.
[?]
заранее размерность массива не известна, поэтому у человека и возникло желание передать размерность через переменные.
но тем не менее, я это грамотным не считаю. использование ReDim оправдано только в том случае, если во время выполнения скрипта размерность массива меняется. но даже в этом случае, действительно грамотные люди создают массив с размерностью заведомо больше той, что потенциально может появится. и только если вариация этого самого индекса большая но нестабильная и чтобы почем зря память не бить, делают его размер Reallocatable, что в контектсе AutoIt равноценно использованию ReDim. почему? производительность. переразмещение массива в памяти (особенно в цикле) - процесс довольно времязатратный (см. пример madmasles)
PS: аналогия с мытьем рук - неуместна. ибо мыть руки - факт общепризнанный. использование массива 1х1 при каждом использовании массивов - нет. я бы даже сказал наоборот. так что, смело можешь адресовать эту фразу самому себе ;)
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
madmasles сказал(а):
С большим объемом данных делается это очень долго.

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