前言
技术群里发了一道字符串算法题,群里开始热闹起来了,刚好手里的需求提测了,闲着也是闲着,写写代码研究一下。
问题
统计字符串中出现最多的字母与个数?
var str = ‘wodexiaomaojiaoxiaohei’;
分析
- 检验字符串 边界处理
- 字符串转换为数组
- 统计所有字母出现的次数
思路出来就开始迈开第一步,具体实现如下:
const str = "wodexiaomaojiaoxiaohei";
function mostTimes(str) {
// 检验字符串格式
if (typeof str !== 'string' || !str) {
return
}
// 将字符串转换为数组
const arr = str.split('')
const obj = {}
arr.forEach((item, index) => {
if (obj[item]) {
obj[item] = {
times: Number(obj[item].times) + 1,
first: obj[item].first,
lastfirst: index
}
} else {
obj[item] = {
times: 1,
first: index,
lastfirst: index
}
}
});
console.log(obj)
// 统计字符最多的字母
// 首先统计各个字母的字数
let tempArr = []
for (const i in obj) {
tempArr.push(obj[i].times)
}
// 对次数排序
tempArr.sort()
// 字母最多的次数
const maxTimes = tempArr[tempArr.length - 1]
let el = ''
for (const i in obj) {
if (obj[i].times == maxTimes) {
// 次数最多的字母
el = i
}
}
console.log(el, maxTimes)
}
mostTimes(str)
运行结果如图所示:

这个方案进行了最笨的数组遍历,两次对象遍历,可以说性能有点差,不过这种方案,在处理的时候方便汇总其它的信息,比如出现次数最后的字母首次出现的位置、最后一次出现的位置。
不过怎么进行优化,让性能更好一些呢。思路优化和语法糖优化?我陷入了沉思.....
优化
- 优化一:
字符串符合迭代器规则,可以直接对字符串遍历,可以减少字符串到数组的转换操作。其次将字符串整合为对象的处理,可以使用
for in
语法糖
// const arr = str.split('') // 删除
const obj = {}
for(let i of str) {
if (i in obj) {
obj[i] ++
} else {
obj[i] = 1
}
}
2)优化二:
拿到字母的次数数组,快速获取到数组中的最大值,目前的处理是先排序,在取值。🤦️,这里可以直接使用 Math.max()
来处理,数字可以通过 ...
拉平。
// 对次数排序
// tempArr.sort()
// 字母最多的次数
// const maxTimes = tempArr[tempArr.length - 1]
const maxTimes = Math.max(...tempArr)
现在的实现如下:
const str = "wodexiaomaojiaoxiaohei";
function mostTimes(str) {
// 检验字符串格式
if (typeof str !== 'string') {
return
}
const obj = {}
for(let i of str) {
if (i in obj) {
obj[i] ++
} else {
obj[i] = 1
}
}
console.log(obj)
// 统计字符最多的字母
// 首先统计各个字母的字数
let tempArr = []
for (const i in obj) {
tempArr.push(obj[i])
}
// 字母最多的次数
const maxTimes = Math.max(...tempArr)
let el = ''
for (const i in obj) {
if (obj[i] == maxTimes) {
// 次数最多的字母
el = i
}
}
console.log(el, maxTimes)
}
mostTimes(str)
运行结果如图所示:

总结
一道小题,从开始思考实现思路到能够自主发现问题,进行优化尝试和解决问题,这应该是作为一个技术开发的基本素质。这道逻辑题目还有很大的优化空间,后续会有时间会继续优化的。