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的颜色选择插件实例代码
Oct 02 Javascript
javascript五图轮播切换实用版
Aug 17 Javascript
js如何获取file控件的完整路径具体实现代码
May 15 Javascript
javascript初学者常用技巧
Sep 02 Javascript
一种新的javascript对象创建方式Object.create()
Dec 28 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
Aug 03 Javascript
angularjs实现多张图片上传并预览功能
Feb 24 Javascript
最新Javascript程序员面试试题和解题方法
Nov 23 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
Dec 13 Javascript
详解javascript 正则表达式之分组与前瞻匹配
May 30 Javascript
JavaScript事件委托原理与用法实例分析
Jun 07 Javascript
vue Tab切换以及缓存页面处理的几种方式
Nov 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+javascript液晶时钟
2006/10/09 PHP
php上的memcache和memcached两个pecl库
2010/03/29 PHP
PHP数据类型之布尔型的介绍
2013/04/28 PHP
js鼠标滑轮滚动事件绑定的简单实例(兼容主流浏览器)
2014/01/14 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
javascript 事件处理示例分享
2014/12/31 Javascript
javascript正则表达式基础知识入门
2015/04/20 Javascript
使用jquery判断一个元素是否含有一个指定的类(class)实例
2017/02/12 Javascript
浅谈nodejs中的类定义和继承的套路
2017/07/26 NodeJs
详解vue-cli项目中用json-sever搭建mock服务器
2017/11/02 Javascript
Webpack实战加载SVG的方法
2017/12/26 Javascript
vue 动态修改a标签的样式的方法
2018/01/18 Javascript
Node.js实现mysql连接池使用事务自动回收连接的方法示例
2018/02/03 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
JS中数据结构与算法---排序算法(Sort Algorithm)实例详解
2019/06/17 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
js实现上传图片并显示图片名称
2019/12/18 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
[02:07]2018DOTA2亚洲邀请赛主赛事第三日五佳镜头 fy极限反杀
2018/04/06 DOTA
[01:20]2018DOTA2亚洲邀请赛总决赛战队LGD晋级之路
2018/04/07 DOTA
Python中模块string.py详解
2017/03/12 Python
查看django执行的sql语句及消耗时间的两种方法
2018/05/29 Python
Python 通过调用接口获取公交信息的实例
2018/12/17 Python
Python为何不能用可变对象作为默认参数的值
2019/07/01 Python
Python通过正则库爬取淘宝商品信息代码实例
2020/03/02 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
5 个强大的HTML5 API 函数推荐
2014/11/19 HTML / CSS
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
约瑟夫·特纳男装:Joseph Turner
2017/10/10 全球购物
实现向右循环移位
2014/07/31 面试题
音乐表演专业毕业生求职信
2013/10/14 职场文书
小学课外活动总结
2014/07/09 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
工商局领导班子存在的问题整改措施思想汇报
2014/10/05 职场文书
交通事故起诉书
2015/05/19 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书