原生JS | 当兔子遇到鸡

HTML5学堂-码匠:当兔子遇到鸡,会怎样呢?先别急,看个小视频~
视频内容

当兔子遇到鸡 —— 不要害怕和别人不一样,在这个世界上,你就是独一无二的自己!

不知道有多少程序在看到这个小视频的时候,想到的不是“复活节”彩蛋,而是“鸡兔同笼问题”……

如果你想到的是“鸡兔同笼”,那么恭喜你,至少你不是一个人……(表示看到兔子从蛋里钻出来的时候,竟然完全没有怀疑 )。

鸡兔同笼问题

鸡兔同笼-起源

“鸡兔同笼问题”是我国古算书《孙子算经》中著名的数学问题,其内容是:“今有雉(鸡)兔同笼,上有三十五头,下有九十四足。问雉兔各几何。”

前端实现鸡兔同笼的计算功能

功能特效:

如果你具有一定JS基础,不妨尝试书写一下或想一想,再看“功能实现”,涉及到的小细节知识可不少,特别是没有内容的对象({})的检测方法。

鸡兔同笼功能的基本实现

鸡兔计算的核心公式

兔子数量 = 脚数 / 2 - 头数;

鸡数量 = 头数 - 兔子数量。

Tips:当然,如果你考虑用for循环,从1只兔子到N只兔子,一个一个尝试组合,也并非不可,但是循环匹配的方法计算效率实在是太低了,并不推荐。另外,关于公式的“推导”过程,可详见下图:

核心功能函数

function caculate(head, foot) {

    var result = {};
    var rabbit = foot / 2 - head;
    var chicken = head - rabbit;
    if (rabbit * chicken > 0 && parseInt(rabbit) == rabbit) {
        result = {
            'rabbit' : rabbit,
            'chicken' : chicken
        }
    };
    return result;
}

注意,此处增加了一个if判断。

rabbit * chicken > 0 用于保证至少有一只鸡、一只兔(能够防止负值和0的出现)

parseInt(rabbit) == rabbit 用于防止小数的产生。

无论是0、负数、还是小数,针对这个实例都是不合法的,因此需要进行控制。在有合法结果时返回一个对象,而在没有合法结果时返回一个空的对象 - {}

对象的检测

如何检测一个没有内容的对象呢?这个问题反而成为了解决“鸡兔同笼”功能需求的关键。

码匠:如何判断一个对象是没有内容的?

码匠好友:判断{}是否等于{}?

码匠:{} == {} 是不可能成立的,虽然两个对象都是没有内容的,但是这是两个对象。所以该方法不可行……

码匠好友:让{}与null相比较?{}不是没有内容吗?

码匠:虽然{}对象当中没有内容,但是它并不等于null。所以该方法也是不可行的。

码匠好友:进行长度检测?

码匠:length属性可用于数组,但不能用于对象。

码匠好友:使用for-in循环进行枚举总可以了吧!(详见如下检测案例1)

码匠:枚举的确能够实现,但是太过繁琐,可以其他一些方法进行实现。(详见如下检测案例2、3)

检测案例1 - 利用for-in循环枚举

var obj = {};
function checkObj(obj) {
    for(var i in obj) {
        if(obj.hasOwnProperty(i)){
            return false; // 不为空对象

        }
    }

    return true; // 空对象,返回true

}
checkObj(obj);

相关说明:使用for-in循环进行枚举,对于没有内容的空对象({}),i值并不会被赋值,for-in中的内容也不会执行。

对于hasOwnProperty的检测,主要是让方法检测该属性是否是自身属性,而非原型链上(继承而来)的属性。

类似方法:使用Object.keys(obj);

Object.keys(obj); 该方法类似于枚举,但是,是直接调用Object的keys方法,方法的返回值为 —— 所有可枚举属性的字符串数组。如果当前对象为空({}),则返回一个空数组。

var obj = {};
var checkResult = Object.keys(obj);
console.log(checkResult.length);

检测案例2 - 利用JSON.stringify方法

var obj = {};
console.log(JSON.stringify(obj) == '{}')

JSON.stringify()方法,用于将JSON对象转换为字符串,当将对象转换为字符串之后,自然就可以和另一个字符串相比较了~~~

在本案例中,HTML5学堂(码匠)选用的是该种方法。

第3方法:getOwnPropertyNames

Object.getOwnPropertyNames()方法,返回对象中,除了原型属性之外的所有属性(包括不可枚举属性),返回的内容为数组,如果该对象没有属性,则返回空数组。

由于该方法返回值为一个数组,因此可以通过length属性,进行判断,如果length长度为0,则代表该对象为空。

var obj = {};
var checkResult = Object.getOwnPropertyNames(obj);
console.log(checkResult.length);

完整功能代码

结构代码

行为代码

涉及到的细节知识

字符串转换为数字

通过input获取到的值,类型为字符串,需要优先转换为数字,再进行操作,在本案例中HTML5学堂(码匠)选用的是Number方法。

NaN的基本检测

当用户在input中输入非数字或不合法数字时,会通过上面的Number方法转换为NaN。

当出现NaN时,则需要给用户给予反馈,而不是继续进行运算,因此需要进行NaN进行检测。

NaN检测的方法很简单,让其与自身相比较,如果自己和自己不相等,那么,该值为NaN

整数检测

在鸡兔同笼计算当中,有可能用户输入的内容是合法数字,也是合法整数,但是有可能在运算之后变成小数。这种情况,是由于用户输入了不成立的数字组合。例如:头3只,脚7只。

对于此类问题,需要借助数字取整来检测,此处HTML5学堂(码匠)使用的是parseInt方法,针对兔子的数字取整,然后再跟原始的兔子数字比较,如果相同,则原始数字为整数。

没有内容的对象检测

在上面已经进行了详细讲解,在此罗列一下检测没有内容的对象的方法:

● JSON.stringify(obj);

● Object.keys(obj);

● Object.getOwnPropertyNames(obj);

查看效果实例:https://codepen.io/majiang/pen/oWoGmz

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2017-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

史上最简单!冒泡、选择排序的Python实现及算法优化详解

1、排序概念 内部排序和外部排序 根据排序过程中,待排序的数据是否全部被放在内存中,分为两大类: 内部排序:指的是待排序的数据存放在计算机内存中进行的排序过程;...

5284
来自专栏算法channel

不基于比较的基数排序原理图解

主要推送关于对算法的思考以及应用的消息。坚信学会如何思考一个算法比单纯地掌握100个知识点重要100倍。本着严谨和准确的态度,目标是撰写实用和启发性的文章,欢迎...

48113
来自专栏专知

关关的刷题日记12——Leetcode 189. Rotate Array 方法1、2、3

关小刷刷题12 – Leetcode 189. Rotate Array 方法1、2、3 题目 Rotate an array of n elements to...

3718
来自专栏Golang语言社区

深入解析快速排序算法的原理及其Go语言版实现

快速排序是一种基于分治技术的重要排序算法。不像归并排序是按照元素在数组中的位置对它们进行划分,快速排序按照元素的值对它们进行划分。具体来说,它对给定数组中的元素...

3545
来自专栏python3

python3--类的组合,初始类的继承

圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长

1582
来自专栏Golang语言社区

Golang语言关于零值的定义

原文:https://golang.org/ref/spec#The_zero_value The 零值 当一个变量或者新值被创建时, 如果没有为其明确指定初始...

36411
来自专栏鸿的学习笔记

两个字符串算法

这部分主要使用了动态规划的技术,就是如果两个最大公共子序列相等的话,必然前面的也相等

542
来自专栏编程之旅

唠唠快速排序算法

每一个从事计算机相关方向工作的同学一定听说过快速排序算法,在面试的准备过程中,快排也一定是一个必须要牢牢掌握的算法。那么今天就来唠唠快速排序算法。

1132
来自专栏算法channel

常用排序算法代码兑现

主要推送关于对算法的思考以及应用的消息。坚信学会如何思考一个算法比单纯地掌握100个知识点重要100倍。本着严谨和准确的态度,目标是撰写实用和启发性的文章,欢迎...

35811
来自专栏轮子工厂

设计模式(一) | 啥是工厂模式和策略模式?

772

扫码关注云+社区

领取腾讯云代金券