系列文章
- [ CodeWar ] - 001:过滤重复字符
- [ CodeWar ] - 002:最大和最小值
- [ CodeWar ] - 003:判断质数
- [ CodeWar ] - 004:处理数组元素
- [ CodeWar ] - 005:用户分组
- [ CodeWar ] - 006:数组比对
- [ CodeWar ] - 007:找不同
- [ CodeWar ] - 008:分割字符串
- [ CodeWar ] - 009:哈希标签生成器
- [ CodeWar ] - 010:大数相加
- [ CodeWar ] - 011:最短路径
- [ CodeWar ] - 012:rgb 转 hex
- [ CodeWar ] - 013:解析化学式
- [ CodeWar ] - 014:解析公有质因
题目

需求:
- 输入是一个全是整数的列表
- 需要找到它们的质因数,以从小到大的顺序排列
- 并且每个质因素,要算出它所对应的合数集合的总和
解析
这道题乍一看挺唬人的,不过实际上要比解析化学式那道简单许多,至少思路比较直接:
- step 1:计算出每个整数的所有质因并去重
- step 2:合并所有质因并去重
- step 3:遍历得到的质因数集合,将拥有相同质因数的整数放进同一组
- step 4:计算每一组整数的和
- step 5:将质因数集合与和的集合排序后合并成返回的格式
const getPrimeFactor = (num) => {
num = Math.abs(num)
let i = 2,
ret = [],
loop = num - i + 1
while (loop--) {
while (num % i === 0) {
num /= i
ret.push(i)
}
i++
}
return [...new Set(ret)]
}
function sumOfDivided(lst) {
if (lst.length === 0) return []
let allPrimeFactor = [...new Set(lst.map((num) => getPrimeFactor(num)).reduce((pre, cur) => [...pre, ...cur]))].sort(
(a, b) => a - b
)
let allSum = allPrimeFactor
.map((p) => {
let ret = []
lst.forEach((num) => {
if (num % p === 0) {
ret.push(num)
}
})
return ret
})
.map((cl) => cl.reduce((pre, cur) => pre + cur, 0))
return allPrimeFactor.map((p, i) => [p, allSum[i]])
}
优化
虽然上述代码已经解决了问题,但思路挺傻的,这里我们看看应该怎么进行优化。
这里我们先声明几个数组:
i:输入的数组p:用于存储小于max的所有质数s:用于存储拥有相同质因的数o:输出的数组
- 首先我们可以找出输入列表的最大值,在一次循环中依次处理每个数
- 当循环开始的时候,首先判断
p中有没有能够整除i的数,如果有则说明i是质数 - 接下来先将
i加进p,然后遍历i,看是否有数能够被i整除,如果有则说明i是其质因,将这个数加入s - 当
s的长度不为 0 的时候则说明存在能被i整除的数,计算s的总和,并且与i一组加入o中 - 最后返回
o
const sumOfDivided = (lst, max = Math.max(...lst.map(Math.abs)), pris = [], sums = [], rets = []) => {
for (i = 2; i <= max; ++i) {
pris.some((p) => i % p === 0) ||
(pris.push(i) && (sums = lst.filter((n) => n % i === 0)).length && rets.push([i, sums.reduce((a, b) => a + b)]))
}
return rets
}