影响值后,变量始终为0

时间:2017-08-19 18:51:06

标签: javascript algorithm hashmap

我正在尝试用字符串创建哈希映射,地图采用以下形式:

{ 'char': charOccurrence }

这是我的代码:

function compress(text) {
  let hash = new Map();
  let prev = [];
  for (let i = 0; i < text.length; i++) {
    let count = 0;
    prev.push(text[i]);
    for (let j = i+1; j < text.length; j++) {
      // if (prev.indexOf(text[j]) !== -1) break;
      if (text[i] === text[j]) {
        count += 1;
        console.log(count);
      }
    }
    hash.set(text[i], count);
  }
  console.log(hash);
}

compress('aaaaahhhheaaadeee');

问题是count始终为0,即使在影响for循环中的值之后,我也不知道这是怎么回事。这就是我从这段代码中得到的结果:

Map { 'a' => 0, 'h' => 0, 'e' => 0, 'd' => 0 }

我在这里缺少什么?

3 个答案:

答案 0 :(得分:5)

您正在覆盖之前的结果。

每次看到“a”时,你都会在0开始计数,然后读取字符串的其余部分,然后覆盖 hash中的任何内容,作为你的总数找到。字符串中的最后一个“a”将得到总计数0.这就是每个字母都会发生的事情。

prev,你没有做任何事情,或许是为了防止这种情况发生。 (你可以跳过你已经计算过的字母。)

这是一种更简单(更快)的方法:

function compress(text) {
  let hash = new Map();
  for (let i = 0; i < text.length; i++) {
    hash.set(text[i], (hash.get(text[i]) || 0) + 1);
  }
  return hash;
}

console.log(compress('aaaaahhhheaaadeee'));
// Map { 'a' => 8, 'h' => 4, 'e' => 4, 'd' => 1 }

答案 1 :(得分:1)

请注意,您将char:count对的任何现有实例替换为零计数的最后一个匹配实例(不再是这样的char)。

因此,仅对第一个char出现进行hash.set操作 - 在第二个for循环之前检查密钥存在,并仅在需要时执行该循环。

答案 2 :(得分:1)

问题是,在某一点上,计数将不止一个,并且将被写入哈希值,但是当你在字符串中继续前进时,你将最终遇到一些重复的char,并开始再次计算该字符,现在不再出现在字符串的其余部分,因此您在此时用0覆盖散列条目。

对于所有字符都会发生这种情况:每个字符的最后一次出现都会使您在散列中写入0。

但我想知道为什么你使用prev数组,而你已经拥有的Map是管理计数的最佳工具:

function compress(chars) {
  return [...chars].reduce( (hash, c) => 
      hash.set(c, (hash.get(c) || 0) + 1),
      new Map
  );
}

var hash = compress('aaaaahhhheaaadeee');

console.log([...hash]);
.as-console-wrapper { max-height: 100% !important; top: 0; }