阶乘
在数学上, 自然数n的阶乘写作n!。一个正整数 n 的阶乘, 就是所有小于等于 n 的正整数的乘积,0的阶乘为1。比如:
5! = 5 4 3 2 1 = 120
n | n! |
---|---|
0 | 1 |
1 | 1 |
2 | 2 |
3 | 6 |
4 | 24 |
5 | 120 |
6 | 720 |
7 | 5 040 |
8 | 40 320 |
9 | 362 880 |
10 | 3 628 800 |
11 | 39 916 800 |
12 | 479 001 600 |
13 | 6 227 020 800 |
14 | 87 178 291 200 |
15 | 1 307 674 368 000 |
问题: 求自然数n的阶乘
1 | /** |
使用尾递归的方法1
2
3
4
5
6
7
8/**
* @param {number} n
* @param {number} total
* @return {number}
*/
export default function factorial(n, total = 1) {
return n === 1 ? total : factorial(n - 1, n * total);
}
斐波那契
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用。
n | Fibonacci (n) |
---|---|
1 | 1 |
2 | 1 |
3 | 2 |
4 | 3 |
5 | 5 |
6 | 8 |
7 | 13 |
问题: 求斐波那契数列的第n个数字
1 | // 采用递归方法 |
1 | // 使用尾递归优化 |
1 | // 使用解构赋值+循环 |
1 | // 使用生成器 |
素数
素数(又叫质数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
例如: 2,3,5,7,11,13,17,19,23,29,31,37…
问题: 判断自然数n是否是素数
1 | /** |
欧几里得算法
在数学中,欧几里德算法,是计算两个数的最大公约数(GCD)的一种有效方法。两个数的最大公约数是指不留余数即可将两个数整除的数中最大的数。
欧几里德算法是基于如果用大数与小数的差代替大数,两个数的最大公约数不变的原理。例如,21 是 252(21 21) 与 105 (21 5)的最大公约数,那么 21 同时也是 105 和 252 - 105 = 147 的最大公约数。由于这个替换减少了两个数字中较大的一个,重复这个过程会连续地给出较小的一对数字,直到两个数字相等为止。当出现这种情况时,它们是原始两个数字的GCD。
通过颠倒这些步骤,GCD可以表示为每个原始数乘以正整数或负整数的和,例如21=5×105+(-2)×252。GCD总是可以用这种方式表达的事实被称为裴蜀定理。
问题: 利用欧几里得算法求两个数的最大公约数
递归1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* Recursive version of Euclidean Algorithm of finding greatest common divisor (GCD).
* @param {number} originalA
* @param {number} originalB
* @return {number}
*/
export default function euclideanAlgorithm(originalA, originalB) {
// Make input numbers positive.
const a = Math.abs(originalA);
const b = Math.abs(originalB);
// To make algorithm work faster instead of subtracting one number from the other
// we may use modulo operation.
return (b === 0) ? a : euclideanAlgorithm(b, a % b);
}
循环1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20/**
* Iterative version of Euclidean Algorithm of finding greatest common divisor (GCD).
* @param {number} originalA
* @param {number} originalB
* @return {number}
*/
export default function euclideanAlgorithmIterative(originalA, originalB) {
// Make input numbers positive.
let a = Math.abs(originalA);
let b = Math.abs(originalB);
// Subtract one number from another until both numbers would become the same.
// This will be out GCD. Also quit the loop if one of the numbers is zero.
while (a && b && a !== b) {
[a, b] = a > b ? [a - b, b] : [a, b - a];
}
// Return the number that is not equal to zero since the last subtraction (it will be a GCD).
return a || b;
}
最小公倍数
在算术和数论中,两个整数a和b的最小公倍数、最小公倍数或最小公倍数,通常用LCM(a,b)表示,是可被a和b整除的最小正整数。由于整数被零除是未定义的,只有当a和b都不等于0时,这个定义才有意义。但也有些人定义 lcm(a, 0) = 0
最小公倍数可以这样计算 lcm(a, b) = |a * b| / gcd(a, b)
1 | import euclideanAlgorithm from './euclideanAlgorithm'; |
##