JavaScript实现的一个计算数字步数的算法分享


Posted in Javascript onDecember 06, 2014

这两天看了下某位大神的github,知道他对算法比较感兴趣,看了其中的一个计算数字的步数算法,感觉这个有点意思,所以就自己实现了一个。

算法描述与实现原理

给出一个整型数字,统计出有多少种走法可以到达目标,比如一个数字4,可以有下面几种走法

    [ 1, 3 ]

        [ 4 ]

    [ 1, 1, 2 ]

        [ 2, 2 ]

    [ 1, 1, 1, 1 ]

其实通过上面的组合可以得出下面的结论。

1.先列出所有项是1的组合
2.依次从左到右项为1的组合
3.递归上面的集合,找出项里1的索引,然后计算左起2项的值,结果递归此操作
4.排除1和2的情况

下面先提供三个工具函数:

// 计算数组内的值

function calculate(arg){

    return eval(arg.join('+'));

}
// 输出数组的值

function print(arg){

    for(var i = 0; i < arg.length; i++){

        console.log(arg[i]);

    }

}
// 检查是否是正反的走法

function hasRepeat(src, dist){

    if (dist.length != 2) return false;

    for(var i = 0, len = src.length; i < len ; i++){

        if(dist.length == src[i].length){

            if(dist[0] == src[i][1]){

                return true;

            }

        }

    }

    return false;

}

下面贴出算法的实现:

function countSteps(n){

    var counts = 0,i,j = 0;

    var result = [];

    var newresult = [];

    var source = [];

    var temparg = [];

    // 生成项全为1的数组

    for(i = 1; i <= n ; i++){

        source.push(1);

    }

    if(n > 2){

        for(j = 1; j < n - 1; j++){

            temparg.length = 0;

            if(j < n - 1){

                // 生成从左到右项为1递增的数组

                // 1.. 11.. 111..

                Array.prototype.push.apply(temparg, source.slice(0, j));

                temparg.push(calculate(source.slice(j,n)));

                result.push(temparg.slice(0));

                // 递归数组里的内容,直到项里没有1为止

                combine(temparg.slice(0));

            }

        }

    }

    // 组合包含1的数组项

    // 111->21->3

    function combine(arg){

        var linearg = [];

        for(var i = 0; i < arg.length; i++){

            if(arg[i] == 1){

                if(i ==0 || i == 1){

                    linearg.push(calculate(arg.slice(0,2)));

                    Array.prototype.push.apply(linearg, arg.slice(2, arg.length));

                    if(!hasRepeat(result, linearg)){

                        result.push(linearg);

                        combine(linearg.slice(0));

                    }

                    return;

                }

            }

        }

    }

    //为2的时候比1要多一项

    if(n == 2){

        result.push([2]);

    }

    // 添加全为1的情况

    result.push(source);

    // 输出所有步

    print(result);

    console.log('总共有:' + result.length + '种走法');

}
// 运行

countSteps(4);
// 输出下面内容

/*

    [ 1, 3 ]

    [ 4 ]

    [ 1, 1, 2 ]

    [ 2, 2 ]

    [ 1, 1, 1, 1 ]

    总共有:5种走

*/

总结

这个算法其实可以应用到某类游戏中去,当两个物体之前的距离一定的话,对所有的可能进行业务处理,当然也可以应用到别的地方,虽然大部分前端工程师对算法的实践比较少,不过它还是有存在的价值的,很多UI细节方面其实都运用了算法,以后有空还会贴更多关于算法相关的文章,欢迎大家多提些宝贵意见.

Javascript 相关文章推荐
document.onreadystatechange事件的用法分析
Oct 17 Javascript
JQuery select标签操作代码段
May 16 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
Aug 14 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
JS实现支持多选的遍历下拉列表代码
Aug 20 Javascript
RGB和YUV 多媒体编程基础详细介绍
Nov 04 Javascript
jQuery EasyUI Panel面板组件使用详解
Feb 28 Javascript
全站最详细的Vuex教程
Apr 13 Javascript
js实现json数组分组合并操作示例
Feb 12 Javascript
微信小程序如何使用云开发
May 17 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
Aug 26 Javascript
pnpm对npm及yarn降维打击详解
Aug 05 Javascript
angularjs中的e2e测试实例
Dec 06 #Javascript
angularjs中的单元测试实例
Dec 06 #Javascript
angularjs指令中的compile与link函数详解
Dec 06 #Javascript
angularjs的一些优化小技巧
Dec 06 #Javascript
JavaScript开发人员的10个关键习惯小结
Dec 05 #Javascript
node.js中RPC(远程过程调用)的实现原理介绍
Dec 05 #Javascript
node.js中实现同步操作的3种实现方法
Dec 05 #Javascript
You might like
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
CI框架常用方法小结
2016/05/17 PHP
一个简单安全的PHP验证码类 附调用方法
2016/06/24 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
mac os快速切换多个PHP版本的方法
2017/03/07 PHP
表单项的name命名为submit、reset引起的问题
2007/12/22 Javascript
Javascript 倒计时源代码.(时.分.秒) 详细注释版
2011/05/09 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
js获得网页背景色和字体色的方法
2014/03/21 Javascript
JQuery中的html()、text()、val()区别示例介绍
2014/09/01 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
JS折半插入排序算法实例
2015/12/02 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
Bootstrap树形组件jqTree的简单封装
2016/01/25 Javascript
Vue 过渡实现轮播图效果
2017/03/27 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
Mongoose中document与object的区别示例详解
2017/09/18 Javascript
利用Node.js了解与测量HTTP所花费的时间详解
2017/09/22 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
Nuxt.js 数据双向绑定的实现
2019/02/17 Javascript
JavaScript如何判断对象有某属性
2020/07/03 Javascript
[01:01:13]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第三场
2018/04/06 DOTA
[01:02:30]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第三场 8.22
2019/09/05 DOTA
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
python中的错误如何查看
2020/07/08 Python
Django DRF认证组件流程实现原理详解
2020/08/17 Python
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
幼儿园大班家长评语
2014/04/17 职场文书
四大名著读书笔记
2015/06/25 职场文书
关于五一放假的通知
2015/08/18 职场文书
《月光曲》教学反思
2016/02/16 职场文书
《悬崖边的树》读后感2篇
2019/12/02 职场文书
python 常用的异步框架汇总整理
2021/06/18 Python
MySQL系列之一 MariaDB-server安装
2021/07/02 MySQL