JavaScript常见的算法(三)
1. 兔子问题
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,
小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少?
分析:
1) 兔子的规律为数列1,1,2,3,5,8,13,21…
2) 利用迭代,除了前两个月对数为1,每个月的对数foo(n)=foo(n-1)+foo(n-2)
代码:
const readline=require('readline-sync');
var n = readline.question("请输入月份:");
function foo(n){
if(n==1 || n==2){
return 1;
}else{
return foo(n-1)+foo(n-2);
}
}
console.log("兔子的总对数为"+foo(n));
2. 空气水瓶问题
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
分析:
1)变量sum表示可换的汽水瓶数,n表示空气水瓶数
2)使用while循环,当n>1的时候执行循环体
3)当n=2时,可以借一瓶汽水,然后再换回一瓶; 否则,第一次可以换n/3瓶,然后喝完有空瓶之后再和之前的空瓶相加,再进行循环
代码:
const readline = require('readline-sync');
var n = readline.question("请输入空气水瓶数:");
function foo(n){
var sum = 0;
var r = 0;
var m=0;
while(n>1){
if(n==2){
sum++;
n=1;
}else{
m=Math.floor(n/3);
sum+=m;
r=n%3;
n=r+m;
}
}
return sum;
}
console.log(foo(n));
3. 输出今日日期(以 YYYY-MM-DD 的格式)
输出今天的日期,以 YYYY-MM-DD 的方式,比如今天是 2014 年 9 月 26 日,则输出 2014-09-26
分析:
1) 首先新建一个日期对象d
2) year用来获取年,getFullYear()返回4位的数字
3) month用来获取月,月份比较特殊,0是1月,11是12月。
4) 按照要求,应该把月份变成两位数,使用条件远算符a>b?a:b
5) day用来获取日,按要求使用条件运算符变成两位
代码:
var d = new Date();
var year = d.getFullYear();
var month = d.getMonth()+1;
month = month<10?'0'+month:month;
var day = d.getDate();
day = day<10?'0'+day:day;
console.log(year+'-'+month+'-'+day);
4. 小球反弹问题
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
分析:
1)使用for循环,每次小球反弹时,它的高度减少一半。
2)用length表示小球总共经过的长度,反弹前,长度加上小球的高度,反弹之后,需要再加小球的高度。
代码:
const readline=require('readline-sync');
var n=readline.question("请输入反弹次数:");
function distance(h,n){
var length=0;
for(i=0;i<n;i++){
length+=h;
h*=0.5;
length+=h;
}
console.log("小球在第"+n+"次落地时,共经过"+length+"米,第"+n+"次反弹高度为"+h+"米");
}
distance(100,n);
5. 自守数
`自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n以内的自守数的个数 。
分析:
1) 利用for循环遍历n以内的自然数
2)求出这个数的平方xx
3)使用endsWith()方法判断位数与该数是否相等,相等则输出且个sum加一,
否则继续循环,直到循环结束
4)输出n以内自守数的个数sum
知识点:
1)endsWidth()方法 ----- 字符串方法
endsWith() 方法用于测试字符串是否以指定的后缀结束。
如果参数表示的字符序列是此对象表示的字符序列的后缀,则返回 true;否则返回 false。
注意,如果参数是空字符串,或者等于此 String 对象,则结果为 true。
代码:
const readline=require('readline-sync');
var n=readline.question('请输入n:');
function getX(n){
var sum=0;
for(var i=0;i<=n;i++){
var xx=i*i+'';
if(xx.endsWith(i)){
sum++;
console.log(i);
}
}
console.log(n+'以内自守数的个数为:'+sum);
}
getX(n);
6. 牛顿迭代法和库函数法求立方根
求一个数的立方根。
分析:
有两种方法:牛顿迭代法和Math.cbrt()方法
知识点:
1) toFixed()方法
把数字转换为字符串,结果的小数点后有指定位数的数字:
2) Math.cbrt()方法
Math对象的cbrt()方法用于求一个数的立方根
Math.cbrt(x);
参数x的类型应该是Number。如果x不是Number类型的,那么它会先被强制类型转换为Number类型。
代码:
牛顿迭代法:
const readline=require('readline-sync');
var n=readline.question('请输入一个数:');
function lfg(n){
var x0,xn=1;
var y=xn*xn*xn;
while(y-n>0.1 || y-n<-0.1){
x0=xn;
xn=x0-(x0*x0*x0-n)/(3*x0*x0);
y=xn*xn*xn;
}
return xn.toFixed(2);
}
console.log(lfg(n));
Math.cbrt()方法:
const readline=require('readline-sync');
var n = readline.question('请输入一个数:');
var result=Math.cbrt(n).toFixed(2);
console.log(result);