大三时参加过第七届蓝桥杯,转眼已经两年,最近看了看第九届蓝桥杯试题,打算用JavaScript实现一下。
题目1
标题:分数
1/1 + 1/2 + 1/4 + 1/8 + 1/16 + ….
每项是前一项的一半,如果一共有20项,
求这个和是多少,结果用分数表示出来。
类似:3/2 。当然,这只是加了前2项而已。分子分母要求互质。
注意:
需要提交的是已经约分过的分数,中间任何位置不能含有空格。请不要填写任何多余的文字或符号。
解答:
以下讨论不使用数学公式,仅使用JavaScript编程解决的方法。
class Question1 {
constructor () {
this.result = ''
}
// 辅助方法->求两个数的最小公倍数
lcm (a, b) {
const minNum = Math.min(a, b)
const maxNum = Math.max(a, b)
let temp = 0
for (let i = minNum; i <= maxNum; i++) {
temp = minNum * i
if (temp % maxNum === 0) {
return temp
break
}
}
}
// 辅助方法->求两个数的最大公约数
gcd (a, b) {
const minNum = Math.min(a, b)
const maxNum = Math.max(a, b)
for (let i = minNum; i > 0; i--) {
if (maxNum % i === 0 && minNum % i ===0) {
return i
}
}
}
// 主方法
calculate () {
let a = []
let numerator = 1
let denominator = 1
// 将分数推送进二维数组,第一个元素为分子,第二个元素为分母
for (let i = 0; i < 20; i++) {
a[i] = [numerator, denominator]
denominator *= 2
}
// 求所有分母最小公倍数
let lcmResult = 0
for (let i = 0; i < a.length; i++) {
lcmResult = this.lcm(a[i][0], a[i][1])
}
// numeratorSum (通分后的分子共和,初始化为0)
let numeratorSum = 0
// 分子乘以(最小公倍数/分母),分母都变为lcmResult,即:通分
for (let i = 0; i < a.length; i++) {
a[i][0] *= lcmResult / a[i][1]
a[i][1] = lcmResult
numeratorSum += a[i][0]
}
// 求分子分母最大公约数
const gcdResult = this.gcd(numeratorSum, lcmResult)
// 计算结果
if (gcdResult === 1) {
this.result = numeratorSum + '/' + lcmResult
} else {
this.result = numeratorSum / gcdResult + '/' + lcmResult / gcdResult
}
}
// 展示结果
display () {
console.log('结果为:' + this.result)
}
}
const obj = new Question1()
obj.calculate()
obj.display()
在node环境执行此js文件,如:node Question1.js
,可得到结果为:1048575/524288,如下:
解析请看源码中的注释,请从实例化对象部分(Question1类外)开始阅读。
有空再来做其他题,周末愉快。