zoukankan      html  css  js  c++  java
  • [转]在flash里用array.sort进行随机排序

    hack86在文章《关于随机打乱数组的深入研究》里面写了一个随机数组的方法。

    我不太赞同,同时我希望我可以说明我的论证(学校教给我们要用数据说话 ^_^)
    阿权在这里仅发表一个看法,希望有不同意见的可以给出你的论证,大家交流一下。
    可以PM给我,或者到我网站留言也好啊 http://www.aslibra.com/

    其实随机数组应该不需要这么麻烦,先简单说一下hack86文章里面的方法:
    对于N个元素的数组A,先建立同样N个随机数的临时数组B,然后比较每个数字大小,排序索引数组C,再根据索引C重新编排A

    首先,这个做法是可以的,可总感觉是在做重复的工作。
    其二,你的排序对数字比较就运行了N^2次,实际上用冒泡法来做效率更高些,大概是1~(N-1)的加和次。
    其三,我没看到hack86关于“对Array.sort()内部构造的猜测”是怎么样的猜测。我觉得Array.sort就是一个类似你对数组B的排序,估计是冒泡法排序,你是疑问它内部工作不正常?

    下面,我们来看看Array.sort内部构造,同时比较一下冒泡法,也没啥特别的,测试一下就完事:

    先看看冒泡法:
    (最小的泡泡出现在最后)

    [Copy to clipboard]
    CODE:
    var a_array = Array(21, 545, 154, 15, 845, 45, 568, 784);
    function swap(i, j) {
        a = a_array[i];
        a_array[i] = a_array[j];
        a_array[j] = a;
    }
    var len:Number = a_array.length;
    for (var i:Number = 0; i<len-1; i++) {
        for (var j:Number = 0; j<len-1; j++) {
            if (a_array[j]<a_array[j+1]) {
                swap(j, j+1);
            }
        }
    }
    trace(a_array);

    845,784,568,545,154,45,21,15

    下面看看array.sort
    排序标准是:两个数一直交换,也就是返回1,看看有什么规律:

    [Copy to clipboard]
    CODE:
    function random_me(a, b) {
        return 1;
    }
    var a_array = Array(21, 545, 154, 15, 845, 45, 568, 784);
    for (var i = 0; i<20; i++) {
        a_array.sort(random_me);
        trace(a_array);
    }

    QUOTE:
    545,154,15,845,45,568,784,21
    154,15,845,45,568,784,21,545
    15,845,45,568,784,21,545,154
    845,45,568,784,21,545,154,15
    45,568,784,21,545,154,15,845
    568,784,21,545,154,15,845,45
    784,21,545,154,15,845,45,568
    21,545,154,15,845,45,568,784
    545,154,15,845,45,568,784,21
    154,15,845,45,568,784,21,545
    15,845,45,568,784,21,545,154
    845,45,568,784,21,545,154,15
    45,568,784,21,545,154,15,845
    568,784,21,545,154,15,845,45
    784,21,545,154,15,845,45,568
    21,545,154,15,845,45,568,784
    545,154,15,845,45,568,784,21
    154,15,845,45,568,784,21,545
    15,845,45,568,784,21,545,154
    845,45,568,784,21,545,154,15

    模仿一下,我们也来一样的做法,用冒泡法排序20次,看看有什么规律:

    [Copy to clipboard]
    CODE:
    var a_array = Array(21, 545, 154, 15, 845, 45, 568, 784);
    function swap(i, j) {
        a = a_array[i];
        a_array[i] = a_array[j];
        a_array[j] = a;
    }
    var len:Number = a_array.length;
    for (var m:Number = 0; m<20; m++) {
        for (var i:Number = 0; i<len-1; i++) {
            for (var j:Number = 0; j<len-1; j++) {

                //直接换
                if (true || a_array[j]<a_array[j+1]) {
                    swap(j, j+1);
                }
            }
        }
        trace(a_array);
    }
    QUOTE:
    784,21,545,154,15,845,45,568
    568,784,21,545,154,15,845,45
    45,568,784,21,545,154,15,845
    845,45,568,784,21,545,154,15
    15,845,45,568,784,21,545,154
    154,15,845,45,568,784,21,545
    545,154,15,845,45,568,784,21
    21,545,154,15,845,45,568,784
    784,21,545,154,15,845,45,568
    568,784,21,545,154,15,845,45
    45,568,784,21,545,154,15,845
    845,45,568,784,21,545,154,15
    15,845,45,568,784,21,545,154
    154,15,845,45,568,784,21,545
    545,154,15,845,45,568,784,21
    21,545,154,15,845,45,568,784
    784,21,545,154,15,845,45,568
    568,784,21,545,154,15,845,45
    45,568,784,21,545,154,15,845
    845,45,568,784,21,545,154,15

    看见规律了没?

    比较两个就知道了,就是冒泡法排序的痕迹,只是它的算法是倒着的,具体冒泡法是怎么的就不说了,形象来说就是一个泡泡一直浮上去,重的泡泡就沉下来 o(∩_∩)o...哈哈。
    所以,array.sort就是一个冒泡法,hack86就不需要猜测了。
    同时,冒泡法排序的算法也是最经典的了,效率不用怀疑。
    所以,为什么要怀疑它的内部呢?更加不需要用N^2次的排序算法来代替array.sort

    hack86说:“这几天看到网络上在讨论关于随机打乱数组的问题!发现很多朋友的都有自己的方法,但是否真正的随机了呢?这个问题的争议一直很大,我在总结后,以及对Array.sort()内部构造的猜测后发现,还是有很多不是太完美的地方,所以我经过思考还是写了一套关于自己的数组随机打乱的函数”

    我觉得随机排序是很简单的事情,不必要想的那么复杂,也没有什么争议的,只有算法的优劣。
    你的思路算是普通的也把问题复杂化,效率并不高,何不使用高效的算法?

    对于“真正的随机”,我觉得真正的随机的含义并不是你随机1k次,必须每次都不一样。
    realbobon说“这样产生的随机数不会有重复吗?要是重复了怎么办?”
    既然随机,那就有这个可能性是两个数一样,只是几率很小,但并不影响使用。

    下面看看算法上简便的例子:

    [Copy to clipboard]
    CODE:
    function random_me(a, b) {
        if (Math.random()>0.5) {
            return 1;
        } else {
            return 0;
        }
    }
    var a_array = Array(21, 545, 154, 15, 845, 45, 568, 784);
    for (var i = 0; i<20; i++) {
        a_array.sort(random_me);
        trace(a_array);
    }

    很简单的原理,让array.sort进行操作,每次返回一个随机数,大于0.5就调换两个数。

    我们比较一下效率看看:

    [Copy to clipboard]
    CODE:
    function randomArray(arrLen) {
        var rArr:Array = new Array(arrLen);
        for (var i = 0; i<arrLen; i++) {
            rArr[i] = Math.random();
        }
        return rArr;
    }
    function randomIndex(arrLen) {
        var iArr:Array = new Array(arrLen);
        var rArr = randomArray(arrLen);
        for (var i = 0; i<arrLen; i++) {
            iArr[i] = i;
            var t = rArr[i];
            for (var j = 0; j<arrLen; j++) {
                if (rArr[j]<t) { 

                    iArr[i] = j;
                    t = rArr[j];
                }
            }
            delete t;
            rArr[iArr[i]] = 1;
        }
        return iArr;
    }
    function randomSort(arr) {
        arrLen = arr.length;
        var tArr = new Array(arrLen);
        var iArr = randomIndex(arrLen);
        for (var i = 0; i<arrLen; i++) {
            tArr[i] = arr[iArr[i]];
        }
        return tArr;
    }
    function random_me(a, b) {
        if (Math.random()>0.5) {
            return 1;
        } else {
            return 0;
        }
    }
    //产生随机的数组,填充1000个随机数
    var a_array:Array = new Array();
    for (var i:Number = 0; i<1000; i++) {
        a_array.push(Math.random());
    }
    //
    //开始前一个算法
    var my_date:Date = new Date();
    var time1:Number = my_date.getTime();
    randomSort(a_array);
    var my_date:Date = new Date();
    var time2:Number = my_date.getTime();
    trace(time2-time1);
    //
    //开始后一个算法
    var my_date:Date = new Date();
    var time1:Number = my_date.getTime();
    a_array.sort(random_me);
    var my_date:Date = new Date();
    var time2:Number = my_date.getTime();
    trace(time2-time1);
    我电脑的结果是:
    1157
    281


    我的结论是:
    1 array.sort效率是很高的,没有必要怀疑它,我建议使用它
    2 随机是有一样的可能性,如果你觉得随机有问题,那就是Math.random的问题,要怀疑的本质也是它,相信它,那就相信随机的结果

  • 相关阅读:
    【Docker】解析器指令之 escape
    【Docker】解析器指令之 syntax
    【Docker】Dockerfile 解析器指令
    【Docker】Dockerfile 格式
    【Docker】Dockerfile 介绍
    【Docker】Spring Boot 和 Docker
    【Docker】理解 Docker 中的 OverlayFS
    【Docker】使用 OverlayFS 存储驱动
    【Docker】选择存储驱动
    kuangbin专题 专题一 简单搜索 Fire! UVA
  • 原文地址:https://www.cnblogs.com/sange/p/1656172.html
Copyright © 2011-2022 走看看