【问题标题】:Need help making string input return a histogram that counts frequency of letter pairs需要帮助使字符串输入返回计算字母对频率的直方图
【发布时间】:2019-11-12 13:57:33
【问题描述】:

我需要编写一个函数,它将字符串作为输入并按降序输出字母对频率的直方图。

我设法编写了一个返回单个字符计数的函数,但我不知道如何进行配对。

这是我目前所拥有的:

var string = "etc";
var histogram = {};

for (var i = 0, len = string.length; i < len; i++) {
    var char = string[i];
    if ((string[i] !== " ") && (string[i] !== " ")) {
        histogram[char] = (histogram[char] || 0) + 1;
    }
};

console.log(histogram);

该功能有效,我能够让它将所有空白区域都留在直方图中。不过,我不知道从这里去哪里。如何让它评估对,以及如何遗漏任何单个字符(那些后面没有另一个字符的字符)......非常感谢任何帮助。

【问题讨论】:

  • 我不明白(string[i] !== " ") &amp;&amp; (string[i] !== " ") 为什么要检查string[i] 两次?
  • 你不应该和string[i]+string[i+1]做点什么吗?

标签: javascript arrays string histogram frequency


【解决方案1】:

另一种方法,将问题分解成小块:

const inPairs = (xs) => 
  [...xs].reduce((a, x, i) => i == 0 ? a : [...a, xs[i - 1] + x], [])

const pairFreq = str => str         //   "this is a good thing"
  .split (/\s+/)                    //=> ["this","is","a","good","thing"]
  .filter (s => s.length > 1)       //=> ["this","is","good","thing"]
  .flatMap (inPairs)                //=> ["th","hi","is","is","go","oo","od","th","hi","in","ng"]
  .reduce ( (a, s) => ({...a, [s]: (a[s] || 0) + 1}), {})
                                    //=> {"th":2,"hi":2,"is":2,"go":1,"oo":1,"od":1,"in":1,"ng":1}

console .log (
  pairFreq('this is a good thing')
)

如果您愿意,显然您可以内联inPairs。我喜欢这种转变方式,简单地将步骤串联起来,使我朝着最终目标前进。

【讨论】:

  • 嗯,我得去查一些字符串函数...谢谢你在这里分享。
  • @TCooper:注意这里唯一的字符串函数是split。其他人,filter,'flatMap. and reduce`,在数组上工作。当然我们的辅助函数和主函数也是字符串函数。
  • 很棒的选择。我肯定从这个中学到了很多。谢谢!
  • @ScottSauyet 哦.. DUH。因为 split 可以以某种方式输出一个字符串 XD。你甚至在 cmets 中......无论哪种方式,仍然需要查找 flatmap 的用途,并更多地考虑有效地使用 reduce。这是我昨天忘记的你的 +1。主要是想说我很欣赏这里的方法。非常易读,避免循环。我想如何编写自己的代码。我会和 Barmar 做同样的事情。
  • @TCooper:一位好朋友将不再编写另一个代码作为他的人生目标之一for-loop。
【解决方案2】:

您需要使用string[i+1] 来获取配对中的下一个字母。

并且为避免在使用string[i+1]时访问数组外,循环的限制应为string.length-1

var string = "this is a good thing";
var histogram = {};

for (var i = 0, len = string.length - 1; i < len; i++) {
  if ((string[i] !== " ") && (string[i + 1] !== " ")) {
    let pair = string.substr(i, 2);
    histogram[pair] = (histogram[pair] || 0) + 1;
  }
};

console.log(histogram);

【讨论】:

  • 很好地抓住了冗余——我打算检查一次“”,但在尝试不同的条件时不小心把 && 留在了里面。我是 JS 新手,但我正在阅读您的解决方案以理解它,这完全有道理。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 2018-09-08
  • 2021-12-31
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多