系列文章
- [ 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:解析公有质因
- [ CodeWar ] - 015:字符串解析统计
题目

需求:
- 输入是一个字符串,以一个或多个空格作为分隔符
- 要求找到字符串中出现数量排名前三的子串
- 忽略大小写
- 忽略花里胡哨的符号
解析
这道题的思路比较直接,我们根据需求一步一步来即可:
- 首先通过
split分割字符串,由于是以一个或多个空格作为分隔符,所以在分割完成之后,通过filter过滤掉空项 - 通过
map将字符串转为小写方便比较,通过replace替换掉花里胡哨的符号,通过reduce统计出每个字符串的数量 - 通过
sort以数量进行排序,然后通过slice返回排序的前三个即可
function topThreeWords(text) {
let count = 1,
arr = []
text
.split(' ')
.filter((e) => e)
.map((s) => s.toLocaleLowerCase().replace(/[^a-zA-Z']/giu, ''))
.sort()
.reduce((pre, cur, i, ar) => {
if (pre === cur) {
count += 1
} else {
arr.push([pre, count])
count = 1
}
if (i === ar.length - 1) {
if (pre === cur) {
count += 1
arr.push([cur, count])
} else {
count = 1
arr.push([cur, count])
}
}
return cur
})
arr = arr
.sort((a, b) => b[1] - a[1])
.map((arr) => arr[0])
.slice(0, 3)
.filter((e) => e)
return arr
}
优化
上述代码有好几处可以优化的地方:
replace匹配到数据之后可以直接对匹配到的数据进行操作,所以需要先通过split分割字符串- 同样,也就不需要
sort和filter以及map对分割后的数组进行统一操作 - 对于
{key:value}的格式,JS 中提供了Map方法
那么思路可以改成:
- 通过
replace匹配到每一个子串,在其回调函数中对子串进行处理 - 如果
Map中没有这个key, 则新增这个key,否则key的count + 1 - 去除
Map中花里胡哨的符号key - 返回最终数组
const topThreeWords = (text) => {
let dict = new Map()
text.replace(/[A-z']+(?=[ ]+|$)/g, (match) => {
let word = match.toLowerCase()
dict.set(word, dict.has(word) ? dict.get(word) + 1 : 1)
})
dict.delete("'")
return [...dict]
.sort((a, b) => b[1] - a[1])
.map((a) => a[0])
.slice(0, 3)
}