Содержание

Продвинутое использование массивов

Двумерные массивы с числовыми индексами

Реализация двумерного массива через одномерный требует от нас самого малого: понять, как соотносятся координаты ячеек с шириной двумерного массива. Для этого давайте взглянем на формулу:

N = x + y * WIDTH

Здесь N - это номер ячейки одномерного массива, WIDTH - ширина двумерного массива, а x и y — координаты ячейки в двумерном массиве.

Допустим наш двумерный массив должен иметь ширину 6 и высоту 8 ячеек. Нумерация ячеек как по оси x так и по оси y начинается с нуля. Таким образом номер ячейки с координатами 0,0 в одномерном массиве будет:

N = 0 + 0 * 6 = 0

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

Для понимания, как работает эта формула ознакомьтесь с примером симуляции двумерного массива через одномерный:

! Индексы i1  0..8
local i1_max=9    

! Индексы i2  0..5
local i2_max=6

! Заполнение данных массива
loop local i1 = 0 while i1 < i1_max step i1 += 1:
	loop local i2 = 0 while i2 < i2_max step i2 += 1:
		$двумерный_массив[i1*i2_max+i2]='[<<i1>>,<<i2>>]'
	end
end

! Вывод данных массива
loop local i1 = 0 while i1 < i1_max step i1 += 1:
	loop local i2 = 0 while i2 < i2_max step i2 += 1:
		*p $двумерный_массив[i1*i2_max+i2]+'  '
	end
	*nl
end

*nl

!{Результат 
[0,0]  [0,1]  [0,2]  [0,3]  [0,4]  [0,5]  
[1,0]  [1,1]  [1,2]  [1,3]  [1,4]  [1,5]  
[2,0]  [2,1]  [2,2]  [2,3]  [2,4]  [2,5]  
[3,0]  [3,1]  [3,2]  [3,3]  [3,4]  [3,5]  
[4,0]  [4,1]  [4,2]  [4,3]  [4,4]  [4,5]  
[5,0]  [5,1]  [5,2]  [5,3]  [5,4]  [5,5]  
[6,0]  [6,1]  [6,2]  [6,3]  [6,4]  [6,5]  
[7,0]  [7,1]  [7,2]  [7,3]  [7,4]  [7,5]  
[8,0]  [8,1]  [8,2]  [8,3]  [8,4]  [8,5]  
}

!Получение индексов массива через функцию ARRPOS

local $Поиск = '[2,5]'

local i1 = ARRPOS('$двумерный_массив',$Поиск)/i2_max
local i2 = ARRPOS('$двумерный_массив',$Поиск) mod i2_max

if ARRPOS('$двумерный_массив',$Поиск)<>-1 :
	*Nl $Поиск + '=[<<i1>>,<<i2>>]' 
else 
	*Nl 'Элемент не найден'
end
!{Результат 
[2,5]=[2,5]
}

В данном примере использованы функции:

Двумерные массивы с текстовыми индексами

Пример работы с массивом имеющим текстовые индексы

! Индексы i1  0..3
i1_max=4    

! Индексы i2  0..5
i2_max=6

! Заполнение данных массива 
i1=0
:ПрыгЗадатьМассив1
	i2=0
	:ПрыгЗадатьМассив2
		! Знак двоеточие используется как разделитель 
		! между двумя численными индексами переведенными в текст
		$ДвумерныйМассивТекстовыйИндекс['<<i1>>:<<i2>>']='[<<i1>>,<<i2>>]'
		! $МассивИндекс нужен для дальнейшего поиска через ARRPOS/ARRCOMP
		$МассивИндекс['<<i1>>:<<i2>>']='<<i1>>:<<i2>>'
		! МассивПорядок нужен для использования KILLVAR
		МассивПорядок['<<i1>>:<<i2>>']=ARRSIZE('МассивПорядок')
		! Добавлять новый элемент и удалять нужно 
		!только одновременно в 3х массивах
		
		i2+=1
	if i2<i2_max : Jump 'ПрыгЗадатьМассив2'
i1+=1
if i1<i1_max : Jump 'ПрыгЗадатьМассив1'


! Вывод данных массива
i1=0
:ПрыгВыводМассива1
	*Nl 
	i2=0
	:ПрыгВыводМассива2
		*P $ДвумерныйМассивТекстовыйИндекс['<<i1>>:<<i2>>']+'  '
		i2+=1
	if i2<i2_max : Jump 'ПрыгВыводМассива2'
i1+=1
if i1<i1_max : Jump 'ПрыгВыводМассива1'

*Nl 

!{ Результат 
[0,0]  [0,1]  [0,2]  [0,3]  [0,4]  [0,5]  
[1,0]  [1,1]  [1,2]  [1,3]  [1,4]  [1,5]  
[2,0]  [2,1]  [2,2]  [2,3]  [2,4]  [2,5]  
[3,0]  [3,1]  [3,2]  [3,3]  [3,4]  [3,5]  
}


!Получение индексов массива через функцию ARRPOS
$Поиск='[3,0]'

N=ARRPOS('$ДвумерныйМассивТекстовыйИндекс',$Поиск)
if N<>-1:
	!Ищем разделитель ':'  в индексе
	K=STRPOS($МассивИндекс[N],':')

	i1=VAL(MID($МассивИндекс[N],0,K-1))
	i2=VAL(MID($МассивИндекс[N],K+1,LEN($МассивИндекс[N])-K))

	*NL $Поиск+'=[<<i1>>,<<i2>>]'
else
	*Nl 'Элемент не найден'
end


!{ Результат 
[3,0]=[3,0]
}

*NL
!Удаление элемента массива через текстовый индекс
$Удалить='<<i1>>:<<i2>>'
*NL 'Удаляем элемент с индексом <<i1>>:<<i2>>'

!Получаем номер элемента

N=МассивПорядок[$Удалить]


!Удаляем элемент
KILLVAR '$ДвумерныйМассивТекстовыйИндекс', N
KILLVAR '$МассивИндекс', N
KILLVAR 'МассивПорядок', N

!Еще раз выводим данные массива

i1=0
:ПрыгВыводМассива3
	*Nl 
	i2=0
	:ПрыгВыводМассива4
		if $ДвумерныйМассивТекстовыйИндекс['<<i1>>:<<i2>>']<>'':
			*P $ДвумерныйМассивТекстовыйИндекс['<<i1>>:<<i2>>']+'  '
		else
			*P '[DEL]  '
		end
		i2+=1
	if i2<i2_max : Jump 'ПрыгВыводМассива4'
i1+=1
if i1<i1_max : Jump 'ПрыгВыводМассива3'



!{ Результат
Удаляем элемент с индексом 3:0
[0,0]  [0,1]  [0,2]  [0,3]  [0,4]  [0,5]  
[1,0]  [1,1]  [1,2]  [1,3]  [1,4]  [1,5]  
[2,0]  [2,1]  [2,2]  [2,3]  [2,4]  [2,5]  
[DEL]  [3,1]  [3,2]  [3,3]  [3,4]  [3,5]  
}

В данном примере использованы функции:

Массив переменных

Пример использования индекса в названии массива

! Индексы i1  0..5
i1_max=6    

! Индексы i2  0..2
i2_max=3

! Заполнение данных массива 
i1=0
:ПрыгЗадатьМассив1
	i2=0
	:ПрыгЗадатьМассив2
	!названия заполняемых массивов 
	!$МассивПеременных0 , $МассивПеременных1 , $МассивПеременных2
		DYNAMIC {$МассивПеременных}+i1+{['<<i2>>']='[<<i1>>,<<i2>>]' }
		i2+=1
	if i2<i2_max : Jump 'ПрыгЗадатьМассив2'
i1+=1
if i1<i1_max : Jump 'ПрыгЗадатьМассив1'


! Вывод данных массива
i1=0
:ПрыгВыводМассива1
	*Nl 
	i2=0
	:ПрыгВыводМассива2
		DYNAMIC {*P $МассивПеременных}+i1+{['<<i2>>'] +'  '} 
		i2+=1
	if i2<i2_max : Jump 'ПрыгВыводМассива2'
i1+=1
if i1<i1_max : Jump 'ПрыгВыводМассива1'

!{ Результат 
[0,0]  [0,1]  [0,2]  
[1,0]  [1,1]  [1,2]  
[2,0]  [2,1]  [2,2]  
[3,0]  [3,1]  [3,2]  
[4,0]  [4,1]  [4,2]  
[5,0]  [5,1]  [5,2]   
}

В данном примере использованы функции:


Назад: Как сделать