Что нового

формула для перебора n мерного массива

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Нужна помощь в составлении функции, нужно что бы функция для каждой позиции массива возвращала его индекс, к примеру есть трехмерный массив заданный такими размерами [2][3][3] Всего элементов массива 2 * 3 * 3 = 18. Нужно для каждой позиции от 1 до 18 (или от 0 до 17) определить элемент массива.
К примеру: в первом столбике число, во втором - результат
Код:
0  [0][0][0]
1  [0][0][1]
2  [0][0][2]
3  [0][1][0]
4  [0][1][1]
5  [0][1][2]
6  [0][2][0]
7  [0][2][1]
8  [0][2][2]
9  [1][0][0]
10 [1][0][1]
11 [1][0][2]
12 [1][1][0]
13 [1][1][1]
14 [1][1][2]
15 [1][2][0]
16 [1][2][1]
17 [1][2][2]
Как написать функцию, возвращающая для числа 15 индекс [1][2][0]?
Чувствую что нужно искать где то в переводах из одной системы счисления в другой, но не могу понять как сделать. Функция не должна ограничиваться 3х мерными массивами, в идеале должна уметь считать для n - мерного, даже для [2][3][5][6][1][2] итд массива.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
для варианта от 0 до 17
Код:
Global $aData[2][3][3]
$ddd = 1000
For $i=0 To 1
	For $j=0 To 2
		For $k=0 To 2
			$aData[$i][$j][$k] = $ddd
			$ddd += 1
		Next
	Next
Next

Do
	$iii = Random(0,17,1)
	$code = MsgBox(1,"","index = "&$iii&@CR&"значение = "&inververs($iii,$aData))
Until $code = 2

Func inververs($Position, ByRef $aMass)
	Local $rang = UBound($aMass,0)
	Local $aIndex[$rang]
	For $i = $rang To 1 Step -1
		$size = UBound($aMass,$i)
		$aIndex[$i-1] = Mod($Position,$size)
		$Position = Floor($Position/$size)
	Next
	Local $str = "$aMass"
	For $i=0 to $rang-1
		$str = $str&"["&$aIndex[$i]&"]"
	Next
	Return Execute($str)
EndFunc
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
C2H5OH
Гениально. Спасибо огромное. Думал что будут сложные циклы, переборы, а оказалось все очень компактно.


Добавлено:
Сообщение автоматически объединено:

Маленький вопрос. Если нужно вернуть заполненый массив (2D) всех индексов и значений, то нужно вызывать в цикле функцию или можно сделать проще?
Вот такой:
Код:
[0][0][0] значение 1
[0][0][1] значение 2
итд
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Воот.
Ты озвучил уже готовое решение - в цикле вызвать функцию для каждого элемента.
Что есть "проще" ?
Что именно мы пытаемся "сделать проще"?
Сократить время на разработку? Сократить объем кода(текста кода)? Увеличить быстродействие?


Добавлено:
Сообщение автоматически объединено:

inververs
Так может тебе просто в функции надо поменять

Код:
Return Execute($str)


на

Код:
Return $str
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Сократить объем кода. Подумал, что может получится цикл который выдает на каждом шаге последовательности 000 001 002 010?


Добавлено:
Сообщение автоматически объединено:

Я пока сделал так.
Код:
Func inververs(ByRef $array)
	Local $rang = UBound($array, 0)
	Local $count = 1
	For $i = 1 To $rang
		$count *= UBound($array, $i)
	Next
	Local $return[$count][2]
	Local $result, $position
	For $index = 0 To $count - 1
		$position = $index
		$result = ''
		For $i = $rang To 1 Step -1
			$size = UBound($array, $i)
			$result = '[' & Mod($position, $size) & ']' & $result
			$position = Floor($position / $size)
		Next
		$return[$index][0] = $result
		$return[$index][1] = Execute('$array' & $result)
	Next
	Return $return
EndFunc   ;==>inververs
 
Верх