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 相关文章推荐
jQuery 源代码显示控件 (Ajax加载方式).
May 18 Javascript
js实现全屏漂浮广告移入光标停止移动
Dec 02 Javascript
js全选实现和判断是否有复选框选中的方法
Feb 17 Javascript
Node.js和MongoDB实现简单日志分析系统
Apr 25 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
Jun 23 Javascript
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
Apr 24 Javascript
纯JavaScript实现实时反馈系统时间
Oct 26 Javascript
vue-router 组件复用问题详解
Jan 22 Javascript
vue-lazyload使用总结(推荐)
Nov 01 Javascript
利用Vue实现一个markdown编辑器实例代码
May 19 Javascript
开发中常用的25个JavaScript单行代码(小结)
Jun 28 Javascript
微信小程序分包加载代码实现方法详解
Sep 23 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
2006/11/25 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
Thinkphp调用Image类生成缩略图的方法
2015/03/07 PHP
php解析xml 的四种简单方法(附实例)
2016/07/11 PHP
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
2013/04/28 Javascript
javascript基于DOM实现省市级联下拉框的方法
2015/05/14 Javascript
jQuery实用技巧必备(上)
2015/11/02 Javascript
js实现继承的5种方式
2015/12/01 Javascript
javascript实现平滑无缝滚动
2020/08/09 Javascript
14 个折磨人的 JavaScript 面试题
2016/08/08 Javascript
vue父子组件的数据传递示例
2017/03/07 Javascript
原生Aajax 和jQuery Ajax 写法个人总结
2017/03/24 jQuery
删除table表格行的实例讲解
2017/09/21 Javascript
详解weex默认webpack.config.js改造
2018/01/08 Javascript
微信小程序canvas开发水果老虎机的思路详解
2020/02/07 Javascript
原生JS实现留言板
2020/03/26 Javascript
Vue使用v-viewer实现图片预览
2020/10/21 Javascript
[01:07:57]DOTA2-DPC中国联赛 正赛 Ehome vs Magma BO3 第二场 1月19日
2021/03/11 DOTA
Python 26进制计算实现方法
2015/05/28 Python
Python抽象类的新写法
2015/06/18 Python
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
Python运维开发之psutil库的使用详解
2018/10/18 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
pandas 把数据写入txt文件每行固定写入一定数量的值方法
2018/12/28 Python
Python实现SQL注入检测插件实例代码
2019/02/02 Python
python KNN算法实现鸢尾花数据集分类
2019/10/24 Python
python tkinter canvas使用实例
2019/11/04 Python
VSCODE配置Markdown及Markdown基础语法详解
2021/01/19 Python
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
简单介绍Object类的功能、常用方法
2013/10/02 面试题
网络维护管理员的自我评价分享
2013/11/11 职场文书
幼儿园户外活动总结
2014/07/04 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
2015年教师党员承诺书
2015/04/27 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书
Python机器学习之决策树和随机森林
2021/07/15 Javascript