|
好吧,我不等了……
血戮那个孩子还在忙考试,这个就先发了……
一、代码:
[jass]
globals
location udg_UseLocat = null
//当前使用Location
integer udg_UseAddress = 0
//正在使用的Handle值
integer udg_Digit = 10
//位长,也就是一个支链的长度
endglobals
//辅助函数
function Digit takes integer i returns integer
//获得整数i的位数
local integer TempInt = 0
loop
set TempInt = TempInt + 1
set i = i / udg_Digit
exitwhen i == 0
endloop
return TempInt
endfunction
function GetDigit takes integer i,integer n returns integer
//获得整数i的第n位的值(超过最大位数返回0)
loop
set n = n - 1
exitwhen n == 0
set i = i / udg_Digit
if i == 0 then
return 0
endif
endloop
return i-i / udg_Digit * udg_Digit
endfunction
function FindLocationInList takes location l,integer n returns location
//返回以l为链表头的链表的第n个节点
local integer udg_UseAddress = 0
local integer TempInt = 0
local location udg_UseLocat = null
if GetLocationY(l) == 0 then
set udg_UseLocat = Location(-1,0)
call MoveLocation(l,GetLocationX(l),I2R(udg_UseAddress))
endif
set udg_UseAddress = R2I(GetLocationY(l))
loop
exitwhen n == 0
if GetLocationX(udg_UseLocat) == -1 then
set l = udg_UseLocat
set udg_UseLocat = Location(-1,0)
call MoveLocation(l,I2R(udg_UseAddress),GetLocationY(l))
else
set udg_UseAddress = R2I(GetLocationX(udg_UseLocat))
endif
set n = n - 1
endloop
set l = udg_UseLocat
set udg_UseLocat = null
return l
endfunction
function FindLocationInArray takes location l,integer n returns location
//插入数据r到数组变量l序号为n的位置
local integer udg_UseAddress = 0
local integer TempIntA = Digit(n)
local integer TempIntB = R2I(GetLocationY(l))
local real TempRea = 0
local location udg_UseLocat = null
if TempIntA > TempIntB then
set TempRea = GetLocationX(l)
loop
exitwhen TempIntA - TempIntB == 0
set TempIntB = TempIntB + 1
set udg_UseLocat = Location(-1,TempRea)
set TempRea = I2R(udg_UseAddress)
endloop
call MoveLocation(l,TempRea,I2R(TempIntA))
endif
set TempIntA = R2I(GetLocationY(l))
set udg_UseAddress = R2I(GetLocationX(l))
set l = udg_UseLocat
loop
exitwhen TempIntA == 0
set l = FindLocationInList(l,GetDigit(n,TempIntA))
set TempIntA = TempIntA - 1
endloop
set udg_UseLocat = null
return l
endfunction
function DeleteListLocation takes location l returns nothing
//删除链表
local location udg_UseLocat = null
local integer udg_UseAddress = R2I(GetLocationY(l))
loop
exitwhen udg_UseAddress == -1
set l = udg_UseLocat
set udg_UseAddress = R2I(GetLocationX(l))
call RemoveLocation(l)
endloop
return
endfunction
function DeleteArrayLocation takes integer n,location l returns nothing
//处理带支路的链表
local location udg_UseLocat = null
local integer udg_UseAddress = R2I(GetLocationY(l))
loop
exitwhen udg_UseAddress == -1
if GetLocationY(udg_UseLocat) != 0 then
if n == 1 then
call DeleteListLocation(udg_UseLocat)
else
set n = n - 1
call DeleteArrayLocation(n,udg_UseLocat)
endif
endif
set udg_UseAddress = R2I(GetLocationX(l))
endloop
call DeleteListLocation(l)
set udg_UseLocat = null
return
endfunction
//实际应用函数
function CreateArray takes nothing returns location
//创建数组变量
local integer udg_UseAddress = 0
local location udg_UseLocat = Location(-1,0)
local real TempRea = I2R(udg_UseAddress)
set udg_UseLocat = null
return Location(TempRea,1)
endfunction
function InputDataInArray takes location l,integer n,real r returns nothing
// 输入数据
set l = FindLocationInArray(l,n)
call MoveLocation(l,GetLocationX(l),r)
return
endfunction
function OutputDataInArray takes location l,integer n returns real
// 输出数据
return GetLocationY(FindLocationInArray(l,n))
endfunction
function DeleteArray takes location l returns nothing
// 清除数组
call DeleteArrayLocation(R2I(GetLocationY(l)),l)
call RemoveLocation(l)
endfunction
[/jass]
二、功能:
1、这是一个系统,作用是可以将将数组转化为一种变量类型。
2、这个系统内没有使用真正的数组,所以它并没有8192个上限。
3、因为这个系统创建的数组(为了与真正的数组区别,我称它为L数组)可以存储L数组(甚至是自己),所以很容易组成多维数组(一个L数组变量的元素也是数组)。
三、不足:
1、存储方法是使用了Location组成的链表,并且这个链表自身也是多维的,所以每在L数组内储存一个内容,就要创建一个或多个Location,因此会占用不少内存。
2、代码我还没有优化,只是简单测试下了能够实现功能,不过即使再优化,这个系统所需要运行的代码也不会很少,甚至DeleteArray函数我使用了递归,所以它的运行效率我无法保证。实际上以我自己的水平也无法测试L数组的运行效率比真正的数组慢多少倍。
3、没有批量读取的函数,L数组内的内容只能用给定的函数一个个读取,无法一次获得多个(真正的数组也没这个功能,不过它的效率高,一个个读取并没有问题)
4、当存储序号到多大时会超过代码的执行上限,这个问题没有考虑特别是使用了递归的DeleteArray函数。这个问题可以通过添加某个语句解决。
四、原理及其他介绍:
魔兽里的数组在使用时有两个局限:局域数组时无法传递的,这点大家都知道:另外,数组的8192个元素上限也是个很讨厌的问题。
尽管这两个问题并不是很致命,在一般情况下并不会影响我们的使用,但是这终归是个问题。
虽然我这个系统能够解决这个问题,但是它是以效率为代价的,所以除非特殊需要,这个系统的实际意义不是特别大。
这个系统的基础——Location链表的相关原理以后血戮魔动冰会发帖具体说明,还会有一些效率方面的测试结果,这里只是大概说明一下,关于具体怎么用Location链表实现这个系统的功能我会详细说明。
Location链表,顾名思义,就是通过Location(点)得到的链表,简单来说就是通过一个Location的X轴坐标值来存储下一个结点(也是Location)的Handle,Y轴坐标存储Real型数据——X轴为指针域,Y轴为数据域。这样通过一系列的Location来制作一个链表。因为坐标轴的值是Real型的,所以这个链表能够存储的也是Real型的值。不过我们可以使用I2R(H2I(XX))将一个Handle转化成Real,这样就可以以存储Handle变量了(指针域存储的就是下一个结点的的Handle)。
通过Location链表,我们很简单的就可以组成一个数组,只要用一个Location变量记录下第一个点就可以通过序号来获得对应的存储内容。但是如果我们之接这样做的话,效率是一个无法必须要面对的问题。因为是单向链表,如果我们需要得到一个很大的序号的存储内容时,我们不得不一个个的找过去,这样的话,几乎基本上就没有效率可言了。另外,因为在实际使用时,我们使用的数组序号不会是连续的,如果我们要存储一个数据到很大的序号时,我们不得不天充上之间的空白点,这样,过多的点,也会导致游戏卡死。
现在这个系统使用的方法是构建可变维度的数组。
如图,整个系统就是这个结构,数组时从记录整个L数组的层数(就是有几层链表,图中是二层) 的开始点开始的。
当我们存储一个数据时我们根据存储序号开始运算(求这个存储序号转化为udg_Digit 进制是几位数),如果小于于L数组的层数(图中1到2),那么就按照每层的序号(udg_Digit 进制的每位的值,比如如果udg_Digit 为10,123的第二层序号为2)找到对应的点,如果这个点不存在就创建新的点,如果支路不存在就创建新的支路,直到找到对应的位置,然后修改那个结点的Y轴坐标即可。如果大于L数组的层数(如图2到3),创建一个新的链表,把已有的部分作为这个链表的第一个结点(序号为0)上的支路。,然后同样的找到对应结点,修改Y轴坐标。
读取内容的方法也是差不多的,只是找到结点后不修改,而是通过GetLocationY()读出。
清空的方法有些复杂,简单的说有点像走迷宫,把所有的支链遍历一遍,依次删除。
五、使用说明:
在应用这个系统时,我们只会用到四个函数,其他辅助运行的都不会用到,具体是创建L数组变量的CreateArray函数,在L数组变量中输入元素的InputDataInArray函数
读取L数组变量的OutputDataInArray函数,清除这个变量的DeleteArray函数。
下面我来一次仔细介绍一下使用方法。
1、CreateArray
无参数,因为这个系统创建的L数组在实际上时一个Location变量,所以我们可以这样使用set udg_Array = CreateArray().udg_Array为Location类型变量。
2、InputDataInArray
三个参数,依次是要保存到的L数组的Location类型变量,存储所在的Integer型变量,和作为存储内容的Real型变量。如果我们要在L数组变量udg_Array的序号为10的位置上存入数据实数0.1,那么我们这样使用call InputDataInArray(udg_Array,10,,0.1)。自然,存储的内容也可以使一个Handle变量的Handle值。
3、OutputDataInArray
两个参数,依次是用于读取的L数组的Location类型变量,读取的数据的序号Integer型变量 。如果我们要从L数组变量udg_Array的序号为10的位置上读取一个变量并存到Real型变量udg_Rea中,那么我们可以这样使用set udg_Rea = OutputDataInArray(udg_Array,10) 。
4、DeleteArray
一个参数,就是要清空的L数组变量。直接call DeleteArray(udg_Array)即可。 |
评分
-
查看全部评分
|