算法练习08 找出字符串中出现次数最多的字符

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/duola8789/article/details/84553554

题目

找出一个字符串中出现次数最多的字符

const str = 'asdfaaaa'

最后的返回值是字符串'a'

实现

嗯,我略加思考(半个小时左右),给出了一个复杂的方案,一个屎一般的方案

屎一般的方案

我的方案是利用redcue,计算出了每个字符串出现的频次,存到了一个对象中:

const obj = {a: 5, s: 1, d: 1, f: 1}

然后就是取出其中最大的那一项了,需要对这个对象按照属性值排序了,我当时写的方案就像屎一样

不,我就是一坨屎

我的做法是:

const arr = Object.keys(obj);
let max = 0;
for (let i = 0; i < arr.length; i++) {
  if (obj[arr[i]] > obj[arr[max]]) {
    max = i
  }
}

其实根本没有必要这样。按对象的属性对数组排序懂吗?

const arr = [
  { value: 'a', count: 100 },
  { value: 'b', count: 99 },
  { value: 'c', count: 101 },
]

arr.sort((a, b) => a.count - b.count)

这不就得了吗?直接把上面的obj改造成这个形式就行了

Object.keys(obj).map(v => ({
  value: v,
  count: obj[v]
})).sort((a, b) => b.count - a.count)

所以香喷喷的一坨代码出炉了:

const countStr = str => {
  if (typeof str !== 'string') {
    return ''
  }
  if (str.length === 1) {
    return str
  }
  const obj = [...str].reduce((total, current) = > {
    if (!total[current]) {
      total[current] = 1
    } else {
      total[current] += 1
    }
    return total;
  }, {});

  return Object.keys(obj).map(v = > ({
    value: v,
    count: obj[v]
  })).sort((a, b) = > b.count - a.count)[0].value
};

优化上面那一坨

为什么说是一坨屎呢?我总感觉上面的代码有点傻,话说,我知道我傻,但是当时没办法

要不然直接用for循环试试?好像更简单呢傻逼

const countStr = str => {
  if (typeof str !== 'string') {
    return ''
  }
  if (str.length === 1) {
    return str
  }
  let obj = {};
  let maxChar = '';
  for (let i = 0; i < str.length; i++) {
    if (!obj[str[i]]) {
      obj[str[i]] = 1;
    } else {
      obj[str[i]]++
    }
    if (!maxChar || obj[str[i]] > obj[str[maxChar]]) {
      maxChar = str[i]
    }
  }
  return maxChar;
};

人家直接在生成{a: 5, s: 1, d: 1, f: 1}对象时,结果都出来了好么?知道自己傻逼了吧~

就算是不那么臭的屎还是要优化

知道个屁,我真知道怎么写代码吗二笔?

我当时说,应该用正则,匹配同一个字符,但是咋匹配呢?俺不知道……

废话,就他么这个水平,你说对得起程序员三个字么,以后改叫掏粪工吧

知道了吧?正则表达式里面,用\1就可以取得刚才的捕获组,那怎么捕获相同的字符呢?我傻逼呵呵舔着脸问

告诉你,全都告诉你~!!

([0-9])\1{5}
//匹配连续6个相同的数字

这会懂了吧?懂了懂了,我擦擦掉进嘴里一半的鼻涕

所以呢,然后呢?

我又蒙蔽了,用match还是用exec来着?

match方法,有了g标志符,无论执行多少次,返回的数组都是一样的,都是[ 第一个匹配项,第二个匹配项, 第三个匹配项],捕获组死一边去吧~!!

所以呢,返回了一个这样的数组:

['s', 'bbbbbb' ,'aaaa']

然后排序啊,再问咋排我就扇死自己~

['s', 'bbbbbb' ,'aaaa'].sort((a, b) => b.length - a.length)

别忘了提前对字符串排个序,要不然你匹配个屁连续的字符串~~!!!!!!!

所以给出了又一坨优美的代码,

const countStr = str => {
  if (typeof str !== 'string') {
    return ''
  }
  if (str.length === 1) {
    return str
  }
  return [...str].sort().join('').match(/(\S)\1*/g).sort((a, b) = > b.length - a.length)[0][0];
};

竟然最后弄成了一行代码,真时,要不然说自己一开始的思路就是一坨屎呢~

真香!!

总结

结论就是我太屎了

  1. 正则匹配连续相同字符串
  2. match方法返回结果
  3. 正确组织数组项结果,对数组按照某个属性排序(或者按照长度排序)

参考

猜你喜欢

转载自blog.csdn.net/duola8789/article/details/84553554
今日推荐