首页 > 解决方案 > 在Javascript中查找重复字符串的最后一个索引和字符的相对频率

问题描述

我正在研究一个有趣的 javascript 问题,它应该接受一个字符串并返回嵌套数组,其中包含一个数组,每个重复的字符都包含一个数组。组应具有以下结构:[[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]])

标签: javascriptarrays

解决方案


这是可以解决它的替代解决方案。该.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>


推荐阅读