发表于: 2017-03-30 23:27:22

1 1415


今天完成的事情:

今天状态不太好,注意力老是不集中,一直分神,看书看不进去,看代码也看不进去,过一会儿就想看看手机,搞的一天下来都没做成什么事情,之前的计划也没完成。


明天计划的事情:

明天讲小课堂,先准备资料做PPT,之后若还是有时间,按步骤做任务5,谢页面、阅读HTTP协议、jQuery里Ajax的写法等。


遇到的问题:

暂无


收获:

洗牌算法1:随机抽牌,放在另一组;再次抽取,抽到空牌则重复抽。“抽到空牌则重复抽”这会导致后面抽到空牌的机会越来越大,显然是不合理的。可以优化一步成:牌抽走后,原牌变少。(而不是留下空牌)

function shuffle_pick_1(m) //洗牌 //抽牌法

{

    //生成m张牌

    var arr = new Array(m);

    for (var i=0; i<m; i++) {

        arr[i] = i;

    }

    //每次抽出一张牌,放在另一堆。因为要在数组里抽出元素,把后面的所有元素向前拉一位,所以很耗时。

    var arr2 = new Array();

    for (var i=m; i>0; i--) {

        var rnd = Math.floor(Math.random()*i);

        arr2.push(arr[rnd]);

        arr.splice(rnd,1);

    }

    return arr2;

}

这个也明显有问题,因为数组如果很大的话,删除中间的某个元素,会导致后面的排队向前走一步,这是一个很耗时的动作。

回想一下“我们为什么要删除那个元素?”目的就是为了不产生空牌。

除了删除那个元素之外,我们是不是还有其它方式来去除空牌?

有的,我们把最后一张未抽的牌放在那个抽走的位置上就可以了。

所以,这个思路我们可以优化成这样:

function shuffle_pick(m) //洗牌 //抽牌法优化牌

{

    //生成m张牌

    var arr = new Array(m);

    for (var i=0; i<m; i++) {

        arr[i] = i;

    }

    //每次抽出一张牌,放在另一堆。把最后一张未抽的牌放在空位子上。

    var arr2 = new Array();

    for (var i=m; i>0;) {

        var rnd = Math.floor(Math.random()*i);

        arr2.push(arr[rnd]);

        arr[rnd] = arr[--i];

    }

    return arr2;

}

洗牌算法2:

换牌思路,第i张与任意一张牌换位子,换完一轮即可。

function shuffle_swap(m) //洗牌 //换牌法

{

    //生成m张牌

    var arr = new Array(m);

    for (var i=0; i<m; i++) {

        arr[i] = i;

    }

    //第i张与任意一张牌换位子,换完一轮即可

    for (var i=0; i<m; i++) {

        var rnd = Math.floor(Math.random()*(i+1)),

            temp = arr[rnd];

        arr[rnd] = arr[i];

        arr[i]=temp;

    }

    return arr;

}

洗牌算法3:

插牌思路,

先有一张牌,第二张牌有两个位置可随机插入(第一张牌前,或后),第三张牌有三个位置可随机插入(放在后面,或插在第一位,或插在第二位),依此类推

代码如下:

function shuffle_insert_1(m) //洗牌 //插牌法

{

    //每次生成一张最大的牌,插在随机的某张牌前。因为要在数组里插入元素,把后面的所有元素向后挤一位,所以很耗时。

    var arr = [0];

    for (var i=1; i<m; i++) {

        arr.splice(Math.floor(Math.random()*(i+1)),0,i);

    }

    return arr;

}

以上的代码也会有一些问题:就是随着牌数的增多,插牌变得越来越困难,因为插牌会导致后面的很多牌都往后推一步。

当然,我们也可以适当的优化一下:先有n-1张牌,第n张牌放在最后,然后与任意一张牌互换位置。

代码如下:

function shuffle_insert(m) //洗牌 //插牌法优化版,可以用数学归纳法证明,这种洗牌是均匀的。

{

    //每次生成一张最大的牌,与随机的某张牌换位子

    var arr = new Array(m);

    arr[0] = 0;

    for (var i=1; i<m; i++) {

        var rnd = Math.floor(Math.random()*(i+1));

        arr[i] = arr[rnd];

        arr[rnd] = i;

    }

    return arr;

}


返回列表 返回列表
评论

    分享到