获取字符串中重复次数最多的字符

原创
2021/06/28 22:00
阅读数 208

水一帖: 引用:前端 JavaScript 获取字符串中重复次数最多的字符

输入bianchengsanmei,xuexiyouqudezhishi,jieshiyouqudepengyou,suzaoyouqudelinghun.ii 输出:

  • // 出现次数最多的字符是:i,出现次数为:10
  • // 出现次数最多的字符是:u,出现次数为:10 结果两个
[
  ...[
    ...'bianchengsanmei,xuexiyouqudezhishi,jieshiyouqudepengyou,suzaoyouqudelinghun.ii',
  ]
    .reduce((s, e) => (s.set(e, (s.get(e) || 0) + 1), s), new Map())
    .entries(),
]
  .sort((x, y) => y[1] - x[1])
  .filter((e, i, a) => e[1] == a[0][1]);

输出:

[ [ 'i', 10 ], [ 'u', 10 ] ]

两步,第一步,字符转数组[...str]reduce,打入Map统计字符次数:

const str = 'bianchengsanmei,xuexiyouqudezhishi,jieshiyouqudepengyou,suzaoyouqudelinghun.ii';
const map = [...str].reduce((s, e) => (s.set(e, (s.get(e) || 0) + 1), s), new Map());
//Map(22) { 'b' => 1, 'i' => 10, 'a' => 3,'n' => 6,'c' => 1, 'h' => 5, 'e' => 8,'g' => 3, 's' => 4, 'm' => 1, ',' => 3, 'x' => 2, 'u' => 10,'y' => 4, 'o' => 5, 'q' => 3,'d' => 3,'z' => 2,'j' => 1,'p' => 1,'l' => 1,'.' => 1}

获取map后,转换成数组,排序,排序后第一个即最长,然后filter过滤获取所有和第一个长度一样的:

[...map.entries()].sort((x,y)=>y[1]-x[1]).filter((item, index, array) => item[1] == array[0][1]);
// [ [ 'i', 10 ], [ 'u', 10 ] ]

Ruby解法,Ruby非常灵活,可以一行解决问题,可以用来快速检验算法的预期结果, ruby因为有slice_when,可以不需循环去统计次数,第一步转数组、排序,然后将所有相等的分为同一组 slice_when(&:!=)

irb(main):009:0> str.chars.sort.slice_when(&:!=)
=> #<Enumerator: ...>
irb(main):010:0> str.chars.sort.slice_when(&:!=).to_a
=> 
[[",", ",", ","],
 ["."],
 ["a", "a", "a"],
 ["b"],
 ["c"],
 ["d", "d", "d"],
 ["e", "e", "e", "e", "e", "e", "e", "e"],
 ["g", "g", "g"],
 ["h", "h", "h", "h", "h"],
 ["i", "i", "i", "i", "i", "i", "i", "i", "i", "i"],
 ["j"],
 ["l"],
 ["m"],
 ["n", "n", "n", "n", "n", "n"],
 ["o", "o", "o", "o", "o"],
 ["p"],
 ["q", "q", "q"],
 ["s", "s", "s", "s"],
 ["u", "u", "u", "u", "u", "u", "u", "u", "u", "u"],
 ["x", "x"],
 ["y", "y", "y", "y"],
 ["z", "z"]]
irb(main):011:0>

group_by按长度分组,并统计长度 group_by(&:size),group_by后生成的结果是Hash{key=>value},key是后面传入的block运算结果,value是block运算结果相同的元素,

irb(main):011:0> str.chars.sort.slice_when(&:!=).group_by(&:size)
=> 
{3=>[[",", ",", ","], ["a", "a", "a"], ["d", "d", "d"], ["g", "g", "g"], ["q", "q", "q"]],
 1=>[["."], ["b"], ["c"], ["j"], ["l"], ["m"], ["p"]],
 8=>[["e", "e", "e", "e", "e", "e", "e", "e"]],
 5=>[["h", "h", "h", "h", "h"], ["o", "o", "o", "o", "o"]],
 10=>[["i", "i", "i", "i", "i", "i", "i", "i", "i", "i"], ["u", "u", "u", "u", "u", "u", "u", "u", "u", "u"]],
 6=>[["n", "n", "n", "n", "n", "n"]],
 4=>[["s", "s", "s", "s"], ["y", "y", "y", "y"]],
 2=>[["x", "x"], ["z", "z"]]}

生成的hash按照key来排序 sort_by{_1},或者:sort_by(&:first),或者:sort_by{ |k, v| k },然后取最后一个元素,即结果

irb(main):012:0> str.chars.sort.slice_when(&:!=).group_by(&:size).sort_by{_1}.last
=> [10, [["i", "i", "i", "i", "i", "i", "i", "i", "i", "i"], ["u", "u", "u", "u", "u", "u", "u", "u", "u", "u"]]]

整理去掉重复:.last.map{[_1.uniq.first,_1.size]}

irb(main):013:0> str.chars.sort.slice_when(&:!=).group_by(&:size).sort_by{_1}.last.last.map{[_1.uniq.first,_1.size]}
=> [["i", 10], ["u", 10]]

最后一步.last.map是为了获得和js一样的输出结果,如果只是为了快速验证,可以取 flatten.uniq 即:

irb(main):014:0> str.chars.sort.slice_when(&:!=).group_by(&:size).sort_by(&:first).last.flatten.uniq
=> [10, "i", "u"]

即ruby完整的解决代码:

str.chars.sort.slice_when(&:!=).group_by(&:size).sort_by{_1}.last.last.map{[_1.uniq.first,_1.size]}

最短代码一行解决

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部