javascript - 在Javascript中查找重复字符串的最后一个索引和字符的相对频率
问题描述
我正在研究一个有趣的 javascript 问题,它应该接受一个字符串并返回嵌套数组,其中包含一个数组,每个重复的字符都包含一个数组。组应具有以下结构:[[value, first_index, last_index, times_repeated], ..., [value, first_index, last_index, times_repeated]]
. 使用当前代码,我的值和第一个索引总是正确的,但我很难理解如何找到重复中包含的字符的最后一个索引,以及如何找到重复的频率。
- value:被评估的字符。
- first_index:字符首次出现的索引。
- last_index:最后出现的字符索引。
- times_repeated:字符连续重复的次数。
这是我的代码:
function findRepeating(str) {
const splitter = str.split("");
let arr = [];
const getOccurance = (array, value) => {
let count = 0;
array.forEach((v) => (v === value && count++));
return count;
}
for(i = 0; i < splitter.length; i++){
if(i === 0){
let firstArr = [];
firstArr.push(splitter[i], i, splitter.lastIndexOf(splitter[i]), getOccurance(splitter, splitter[i]));
arr.push(firstArr);
} else {
if(splitter[i] !== splitter[i - 1]){
let nArr = [];
nArr.push(splitter[i], i, splitter.lastIndexOf(splitter[i]), getOccurance(splitter, splitter[i]));
arr.push(nArr);
} else {
continue;
}
}
}
return arr;
}
以下是一些基于字符串输入的预期输出:
Test.assertSimilar(findRepeating(''), [])
Test.assertSimilar(findRepeating('a'), [['a', 0, 0, 1]])
Test.assertSimilar(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
Test.assertSimilar(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
Test.assertSimilar(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Test.assertSimilar(findRepeating('aabbbaabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]])
Test.assertSimilar(findRepeating('1111222233334444'), [['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]])
Test.assertSimilar(findRepeating('1000000000000066600000000000001'), [['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]])
解决方案
这是可以解决它的替代解决方案。该.replace()
方法有一个特殊的替换回调,您可以使用它。您可以向它传递一个参数,/(.)\1*/g
该参数是匹配字符组的正则表达式。然后替换方法给出匹配(m
,即字符组),它在组中匹配的单个字符c
,以及它在 匹配的索引i
。使用所有这些,您可以获得输出所需的所有信息:
const findRepeating = str => {
const res = [];
str.replace(/(.)\1*/g, (m, c, i) => res.push([c, i, i+m.length-1, m.length]));
return res;
}
Test.assertSimilar(findRepeating(''), [])
Test.assertSimilar(findRepeating('a'), [['a', 0, 0, 1]])
Test.assertSimilar(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
Test.assertSimilar(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
Test.assertSimilar(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Test.assertSimilar(findRepeating('aabbbaabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]])
Test.assertSimilar(findRepeating('1111222233334444'), [['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]])
Test.assertSimilar(findRepeating('1000000000000066600000000000001'), [['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]]);
<script>
const Test = {
assertSimilar: (res, arr) => {
console.log(...(JSON.stringify(res) !== JSON.stringify(arr) ? ["Unexpected result:", res, "expected:", arr]: ["Test passed"]));
}
}
</script>
上面的内容有点乱,因为它滥用了.replace()
,这可以通过现代方法以更传统的方式完成,例如.matchAll()
:
const findRepeating = str =>
Array.from(str.matchAll(/(.)\1*/g), ({0: m, 1: c, index}) => [c, index, index+m.length-1, m.length]);
Test.assertSimilar(findRepeating(''), [])
Test.assertSimilar(findRepeating('a'), [['a', 0, 0, 1]])
Test.assertSimilar(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
Test.assertSimilar(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
Test.assertSimilar(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Test.assertSimilar(findRepeating('aabbbaabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]])
Test.assertSimilar(findRepeating('1111222233334444'), [['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]])
Test.assertSimilar(findRepeating('1000000000000066600000000000001'), [['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]]);
<script>
const Test = {
assertSimilar: (res, arr) => {
console.log(...(JSON.stringify(res) !== JSON.stringify(arr) ? ["Unexpected result:", res, "expected:", arr]: ["Test passed"]));
}
}
</script>
推荐阅读
- awk - 如何在文本文件的所有行之间添加 N 个空行?
- node.js - 如何在 mocha 测试中存根 mongodb 的 addCursorFlag?
- android - Expo SDK 更新导致 Playstore 应用程序崩溃(无效 SDK 错误)
- sql - 在 SQL 中按分区对值进行排名
- php - 如何在我的新 Laravel 应用程序中下载在旧应用程序中创建的文件
- c++ - 将指针传递给结构时Qt信号不起作用
- python - 使用列名作为要替换的字符串值执行字符串替换
- google-apps-script - 如何在 Google 表格中返回重定向的 URL
- python - OPEN-CV 错误: (-215:Assertion failed) !ssize.empty() in function 'cv::resize'
- python - 如何在 Pandas 中分组并保留所有列