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 相关文章推荐
让iframe自适应高度(支持XHTML,支持FF)
Jul 24 Javascript
摘自百度的图片轮换效果代码
Nov 19 Javascript
ajax更新数据后,jquery、jq失效问题
Mar 16 Javascript
javascript中打印当前的时间实现思路及代码
Dec 18 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
Mar 25 Javascript
JQuery中DOM实现事件移除的方法
Jun 13 Javascript
jQuery 常用代码集锦(必看篇)
May 16 Javascript
javascript滚轮事件基础实例讲解(37)
Feb 14 Javascript
Vue.set()实现数据动态响应的方法
Feb 07 Javascript
vue中各选项及钩子函数执行顺序详解
Aug 25 Javascript
浅谈Vue3 Composition API如何替换Vue Mixins
Apr 29 Javascript
详解JavaScript匿名函数和闭包
Jul 10 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
《魔兽争霸3》重制版究竟重制了什么?玩家:这么糊弄真的好吗?
2020/05/04 魔兽争霸
PHP Zip解压 文件在线解压缩的函数代码
2010/05/26 PHP
PHP include任意文件或URL介绍
2014/04/29 PHP
yii操作session实例简介
2014/07/31 PHP
ThinkPHP实现带验证码的文件上传功能实例
2014/11/01 PHP
thinkphp3.0输出重复两次的解决方法
2014/12/19 PHP
thinkPHP5.0框架API优化后的友好性分析
2017/03/17 PHP
PHP中Session ID的实现原理实例分析
2019/08/17 PHP
Laravel 错误提示本地化的实现
2019/10/22 PHP
Javascript 个人笔记(没有整理,很乱)
2007/07/07 Javascript
jQuery 操作XML入门
2008/12/25 Javascript
JavaScript几种形式的树结构菜单
2010/05/10 Javascript
jQuery初学:find()方法及children方法的区别分析
2011/01/31 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
JavaScript等比例缩放图片控制超出范围的图片
2013/08/06 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
利用Angularjs和bootstrap实现购物车功能
2016/08/31 Javascript
three.js中文文档学习之如何本地运行详解
2017/11/20 Javascript
一种angular的方法级的缓存注解(装饰器)
2018/03/13 Javascript
微信小程序自定义多列选择器使用详解
2019/06/21 Javascript
移动端手指操控左右滑动的菜单
2019/09/08 Javascript
简洁的十分钟Python入门教程
2015/04/03 Python
浅谈Pandas 排序之后索引的问题
2018/06/07 Python
浅谈Python的list中的选取范围
2018/11/12 Python
对python中的float除法和整除法的实例详解
2019/07/20 Python
python实现根据文件格式分类
2019/10/31 Python
整理的15个非常有用的 HTML5 开发教程和速查手册
2011/10/18 HTML / CSS
全球知名旅游社区巴西站点:TripAdvisor巴西
2016/07/21 全球购物
Dyson加拿大官方网站:购买戴森吸尘器,风扇,冷热器及配件
2016/10/26 全球购物
为智能设备设计个性化保护套网站:caseable
2017/01/05 全球购物
2016年校长新年寄语
2015/08/17 职场文书
python实战之一步一步教你绘制小猪佩奇
2021/04/22 Python
详解缓存穿透击穿雪崩解决方案
2021/05/28 Redis
SpringBoot整合JWT的入门指南
2021/06/29 Java/Android
详解MySql中InnoDB存储引擎中的各种锁
2022/02/12 MySQL
日本官方排名前10的动漫,名侦探柯南上榜,第一是一部创造历史的动漫
2022/03/18 日漫