我正在尝试用字符串创建哈希映射,地图采用以下形式:
{ '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 }
我在这里缺少什么?
答案 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; }