找回密码
 点一下
查看: 5152|回复: 17

数组变量系统

[复制链接]
发表于 2009-4-22 16:10:45 | 显示全部楼层 |阅读模式
好吧,我不等了……
血戮那个孩子还在忙考试,这个就先发了……


一、代码
[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变量记录下第一个点就可以通过序号来获得对应的存储内容。但是如果我们之接这样做的话,效率是一个无法必须要面对的问题。因为是单向链表,如果我们需要得到一个很大的序号的存储内容时,我们不得不一个个的找过去,这样的话,几乎基本上就没有效率可言了。另外,因为在实际使用时,我们使用的数组序号不会是连续的,如果我们要存储一个数据到很大的序号时,我们不得不天充上之间的空白点,这样,过多的点,也会导致游戏卡死。
   
       现在这个系统使用的方法是构建可变维度的数组。
      
         未标题-1.jpg
           
             如图,整个系统就是这个结构,数组时从记录整个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)即可。

评分

参与人数 1威望 +5 收起 理由
血戮魔动冰 + 5 考完了……但还没写完……

查看全部评分

发表于 2009-4-22 16:14:49 | 显示全部楼层
沙发入手
这个可以用来做什么呢?
回复

使用道具 举报

 楼主| 发表于 2009-4-22 16:20:21 | 显示全部楼层
做N维数组,或在函数间传递数组
回复

使用道具 举报

发表于 2009-4-23 14:06:48 | 显示全部楼层
我的数组变量也快好了....这个时机...哎
回复

使用道具 举报

 楼主| 发表于 2009-4-23 15:57:09 | 显示全部楼层
也是同样的原理么?
回复

使用道具 举报

发表于 2009-4-23 16:26:41 | 显示全部楼层
我最近在画画也写了个..不过原理不一样 豆腐的原理估计也和你不一样..
回复

使用道具 举报

发表于 2009-4-23 16:29:16 | 显示全部楼层
不一样.我跟橙子都是因为某些特殊需要而要用到多维数组.考虑到自己的实际用途(二维和三维空间的矩阵乘法)以及效率方面的问题,没有用Location链而用的是全局数组,所以不能像你这个这样突破8191的限制.橙子甚至把它固定化了.
回复

使用道具 举报

发表于 2009-4-23 16:30:36 | 显示全部楼层
引用第5楼linzefei于2009-04-23 16:26发表的  :
我最近在画画也写了个..不过原理不一样 豆腐的原理估计也和你不一样..
刚我发帖的时候还没看到你回帖...
回复

使用道具 举报

 楼主| 发表于 2009-4-23 19:13:51 | 显示全部楼层
Location链表的方法确实效率不是很高,
不过当时编的时候目的是想办法传递局域数组的内容
能够组成多维数组算是附带的效果
恩……
回复

使用道具 举报

发表于 2009-4-23 20:56:59 | 显示全部楼层
现在我用动态栈来传递局部数组变量.不过本质还是链表,相比之下只是不需要创建点而已.
回复

使用道具 举报

 楼主| 发表于 2009-4-23 21:08:12 | 显示全部楼层
动态栈?
VJ?
回复

使用道具 举报

发表于 2009-4-23 21:50:16 | 显示全部楼层
最近有很多人写数组存储系统呀。

不知道有没有人写个通用的野怪分组刷系统?
回复

使用道具 举报

 楼主| 发表于 2009-4-23 22:18:37 | 显示全部楼层
野怪分组刷系统
像DOTA一样一窝一窝的刷?
回复

使用道具 举报

发表于 2009-4-24 20:34:36 | 显示全部楼层
引用第10楼疯人¢衰人于2009-04-23 21:08发表的  :
动态栈?
VJ?
不是VJ,不能自由控制源码..
回复

使用道具 举报

 楼主| 发表于 2009-4-24 20:40:15 | 显示全部楼层
好吧
我是不知道了……
不过难道是JAPI?
……
那个好像是只能本地用的吧……
回复

使用道具 举报

发表于 2009-4-24 21:55:19 | 显示全部楼层
别想得太麻烦,不能通用的东西我是不会做的.也就是普通的数组+链表而已....

单独发了个帖...
回复

使用道具 举报

 楼主| 发表于 2009-4-24 22:51:38 | 显示全部楼层
不是计算机专业的
对某些名词不太清楚……
回复

使用道具 举报

发表于 2009-5-11 20:13:19 | 显示全部楼层

性福时光~!登陆~~~

xhoyew

http://www.sxxfsg.com/   国内成人用品电子够物第一连锁品牌~!性福时光

性福时光(国际)品牌连锁管理总部
网址:http://youa.baidu.com/shop/a13d8230ee3f5b41396ceeec
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-11-23 21:11 , Processed in 0.411948 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表