前言:
学习《算法101》,每天进步一点点,加油💪。
一、罗马数字转整数、Fizz Buzz和计数质数
1.1 罗马数字转整数
罗马数字包含以下七种字符:I, V, X, L,C,D 和 M。
分别对应的数值为:1 ,5,10,50,100,500,1000 。
例如, 罗马数字 3 写做 III,即为三个并列的 1。12 写做 XII,即为 X+II。 26 写做 XXVII, 即为 XX+V+I。
通常情况下,不能出现超过连续三个相同的罗马数字并且罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V(5) 和 X(10) 的左边,来表示 4 和 9。
X 可以放在 L(50) 和 C(100) 的左边,来表示 40 和90。
C 可以放在 D(500) 和 M(1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在1到3999的范围内。
示例:
输入:"III"
输出:3
输入:"IV"
输出:4
输入:"LVIII"
输出:58
输入:"MCMXCIV"
输出:1994
方法一 : 遍历
思路:
先遍历特殊值,如果有特殊值,先累加特殊值,然后用正则去掉特殊值,再遍历剩余的数字。
代码:
const romanToIntOne = function (num) {
const roman = {
IV: 4,
IX: 9,
XL: 40,
XC: 90,
CD: 400,
CM: 900
};
const list = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
let result = 0;
//先遍历特殊值
for (const key in roman){
// 检测输入值是否含有特殊值
if (num.includes(keys)) {
//用正则去掉特殊值
const reg = new RegExp(key);
num = num.replace(reg,'');
result += roman[key];
}
}
for (const i of num) {
//累加正常罗马数
result += list[i];
}
return result;
}
方法二 : switch+includes
思路:
先遍历所有罗马数字进行累加,对于特殊数字的循环,比如:5+1 = 6,而实际是4,相差2,所以需要在结果上减去2,以此类推。
代码:
const romanToIntTwo = function (num) {
let result = 0;
for (const c of num){
switch (c) {
case 'I':
result += 1;
break;
case 'V':
result += 5;
break;
case 'X':
result += 10;
break;
case 'L':
result += 50;
break;
case 'C':
result += 100;
break;
case 'D':
result += 500;
break;
case 'M':
result += 1000;
break;
}
}
//减去特殊组合
if (num.includes('IV') || num.includes('IX')) result -= 2;
if (num.includes('XL') || num.includes('XC')) result -= 20;
if (num.includes('CD') || num.includes('CM')) result -= 200;
return result;
};
1.2 Fizz Buzz
写一个程序,输出从 1 到 n 数字的字符串表示。
如果 n 是 3 的倍数,输出“Fizz”;
如果 n 是 5 的倍数,输出“Buzz”;
如果 n 同时是 3 和 5 的倍数,输出 “FizzBuzz”。
示例:
n = 15,
返回:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
方法一 : 遍历
思路:
只需要判断1 - n的每个数字是否能被3、5、15整除,输出对应的字符串即可。
详解:
1.第一步,申请一个数组 arr,用于存放每个数字转换后字符串。
2.第二步,循环遍历 的每个数字。如果该数字能被15整除(即取余为0),则该数字对应的字符串为 “FizzBuzz”;如果能被3整除,则为 “Fizz”;如果能被5整除,则为 “Buzz”;否则,为该数字即可。
代码:
/**
* @param {number} n
* @return {string[]}
*/
const fizzBuzz = (n) => {
const arr = [];
for (let i = 1; i <= n; i += 1) {
if (i % 15 === 0) { // 被15整除
arr.push('FizzBuzz');
} else if (i % 3 === 0) { // 被3整除
arr.push('Fizz');
} else if (i % 5 === 0) { // 被5整除
arr.push('Buzz');
} else {
arr.push(i.toString());
}
}
return arr;
};
方法二: 字符串累加
思路:
因为 15 的倍数输出 FizzBuzz,正好是 3 的倍数输出的 Fizz 拼接上 5 的倍数输出的 Buzz,所以只需要单独写 2 个 if 判断,将字符串拼接即可。
详解:
1.第一步,申请一个数组 arr,用于存放每个数字转换后字符串;
2.第二步,循环遍历 的每个数字。定义一个空字符串 str,用于临时存放字符串拼接的结果。如果能被3整除,则 str 追加字符串 “Fizz”;如果能被5整除,则 str 追加字符串 “Buzz”;同时能被3和5整除的话,str 的值就为 “FizzBuzz” 了;否则,为该数字即可。
代码:
const fizzBuzz = (n) => {
const arr = [];
for (let i = 1;i <= n; i += 1) {
let str = '';
if (i % 3 === 0) {
str += 'Fizz';
}
if (i % 5 === 0) {
str += 'Buzz';
}
if (i % 3 !== 0 && 5 !== 0) {
str += i;
}
arr.push(str);
}
return arr;
}