找回密码
 点一下
查看: 2437|回复: 11

随机数值的2幂算法

[复制链接]
发表于 2008-4-17 17:43:05 | 显示全部楼层 |阅读模式
思考题:
设置变量: 整数 数组 VALUE
set VALUE[0] = 1
set VALUE[1] = 2
set VALUE[2] = 4
set VALUE[3] = 8
set VALUE[4] = 16
set VALUE[5] = 32
set VALUE[6] = 64
set VALUE[7] = 128
set VALUE[9] = 256
set VALUE[10] = 512
set VALUE[11] = 1024
set VALUE[12] = 2048
set VALUE[13] = 4096
set VALUE[14] = 8192
set VALUE[15] = 16384
set VALUE[16] = 32768

问题: 使用变量VALUE[0]~VALUE[16],计算一个整数 INT ,其范围在 0~64536 之间。 并用整数变量 INDEX 来表示所使用数组变量VALUE所用的索引。
应用: 利用 2 的幂来组合成一个随意的整数。在做装备技能时,这种算法实用性非常大。

以下是具体的函数的写法例子,仅供参考。

[jass]
//============================================================================
//    Math Functions
//============================================================================
// 求余数: (integer)Mod( integer a, integer b)
function Mod takes integer a, integer b returns integer
    return a - (a/b)*b
endfunction
// 求绝对值: (real)Mod( real a )
function Abs takes real a returns real
    if (a >= 0) then
        return a
    else
        return -a
    endif
endfunction
function ValueSetIndex takes integer value returns integer
    local integer i = 0
    local integer j = 0
    local integer count = R2I(Abs(value))
    local integer int   = Mod(value,2)
    local boolean exit  = false
    local boolean end   = false
    local integer array id
    set count = count - int
    loop
        set j = 0
        set i = i + 1
        set exit = false
        loop
            set j = j + 1
            set id = R2I( Pow(2,j) )
            if id - count == 0 then
                // --------------------------------------
                set INDEX = j // 用INDEX记录下索引号
                // --------------------------------------
                set exit = true
            elseif id >= count then
                // --------------------------------------
                set INDEX = j - 1 // 用INDEX记录下索引号
                // --------------------------------------
                set id = R2I( Pow(2,j-1) )
                set exit = true
            endif
            exitwhen exit
        endloop
        set count = count - id
        if count <= 0 or id == 1 then
            set end = true
        endif
        exitwhen (end)
    endloop
    if int == 1 then
        set i = i + 1
        // --------------------------------------
        set INDEX[i+1] = 0 // 用INDEX记录下索引号
    // --------------------------------------
    endif
    return i
endfunction
[/jass]
// PS: (integer)ValueSetIndex(integer value),其中value是一个设定取值范围的整数(上面说过了,就像INT一样),用数组变量 INDEX 记录下计算的索引。
函数所返回的是INDEX所用的索引数。通过索引数,我们可以还原所代入的整数值value。

----->设 INT={ INT| ( 0<=INT<=64536) }

local integer sum      = 0
local integer index    = 0
local integer maxindex = ValueSetIndex( INT )
loop
    set sum   = sum + VALUE[INDEX[index]]
    set index = index + 1
    exitwhen index >= maxindex
endloop

PS: 变量 sum 的最终结果为 INT。也就是说, sum 计算完之后等于INT, 就是 ValueSetIndex()函数所代入的参数
发表于 2008-4-17 18:00:22 | 显示全部楼层
楼主说的应该是用有限数量的攻击防御附加等技能组合出所有的整数加值吧?~~说起来这最初还是由ox大魔王在03年发明的组合法~~


其实……我用的算法并不会去分解那个数然后算出如何才能组合出它~~

我就是无限地除2下去直到0~~然后用余数来判断是否取该index所对应的值~~实际应用中还是这样比较快~~
回复

使用道具 举报

发表于 2008-4-17 18:03:36 | 显示全部楼层
利用2^0~2^15这16个的不同组合的和运算可以表示1~2^16-1内的所有整数
这样可以通过区不同的组合达到去随机数的目的,是这样吗??很高级呢~~

另外,[codes=jass]// 求绝对值: (real)Mod( real a )[/codes]
以上注释是不是应该是[codes=jass]// 求绝对值: (real)Abs( real a )[/codes]呢??(我的代码风格不是很好,作业里的注释一向是凑数的,说错了不要怪我呀~~)
回复

使用道具 举报

发表于 2008-4-17 18:04:46 | 显示全部楼层
我现在要上课去老~~猪头先生你试试看按我的描述把我的算法重现一遍看?~~
回复

使用道具 举报

 楼主| 发表于 2008-4-17 18:07:03 | 显示全部楼层
后面那个注释貌似搞错了。前面的是Mod,求余数,后面的Abs求绝对值。
偶也是初步去算这种类型的东东,分解数据也算是一个思路吧。
那个VALUE就相当于技能了,用缓存记录好技能,然后在ValueSetValue中给单位加上或删除,这样可以相对直观地将实现所要表现的效果。
回复

使用道具 举报

发表于 2008-4-17 19:10:20 | 显示全部楼层
[codes=jass]function ValueSetIndex takes integer value returns integer
    local integer result = 0
    local integer curr = R2I(Abs(value))
    local integer count = -1
    local integer index = -1
    loop
        exitwhen curr == 0
        set index = index + 1
        if Mod(curr, 2) == 1 then
            set count = count + 1
            set INDEX[count] = index
        endif
        set curr = curr / 2
    endloop
    return count
endfunction[/codes]

55555不知道是不是头目的意思额,随便写了一个
回复

使用道具 举报

发表于 2008-4-17 19:29:07 | 显示全部楼层
难道不是一样的么
回复

使用道具 举报

发表于 2008-4-17 19:31:38 | 显示全部楼层
效果一样,但是效率上可能不太一样额
回复

使用道具 举报

 楼主| 发表于 2008-4-17 19:44:28 | 显示全部楼层
貌似用分解方法写的效率要高一些,循环次数要少很多。
回复

使用道具 举报

发表于 2008-4-17 19:52:09 | 显示全部楼层
额,这个分解貌似是双循环额,而且变量比较多,运算次数也多一点吧………………
可能看的不仔细,随便说说的额
回复

使用道具 举报

发表于 2008-4-17 20:36:48 | 显示全部楼层
不但双循环~~而且里面用到Pow()~~次幂函数运算所耗费的cpu时间跟加减乘除是不可同日而语的~~

以32768为例的话~~你单计算一句Pow(2,16)所花的时间就跟除2法整个过程全部除完用时差不多了~~因此这样子效率是比较低的~~因为前者是把2乘16次~~后者全部算完也最多除以16次2~~
回复

使用道具 举报

发表于 2008-4-17 20:41:26 | 显示全部楼层
貌似乘法和加法已经不可同日而语了额………………
说到cpu就想到ics了555

以上请无视~~
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 06:51 , Processed in 0.063290 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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