问题
I wanted to function a function that does this:
const input =“hellooooloo”;
const results = getRepeated(input);
console.log(results) // [(2,3), (4,7), (9,10)]
It returns an array of arrays of indices of the starting and ending index of consecutively repeated chars from a string.
Here is my attempt, it is a O(n^2). I wonder if there is a more elegant and efficient way of achieving this
const input = 'hellooooloo';
const results = getRepeated(input); // // [(2,3), (4,7), (9,10)]
function getRepeated(string) {
const results = []
if(string.length < 2) return results
for(let i = 0; i < string.length - 1; i++) {
if(i > 1 && string[i] === string[i-1]) {
continue
}
let startIndex = i
let endIndex = i
for(let j = i + 1; j < string.length; j++) {
if(string[i] === string[j]) {
endIndex = j
} else {
break
}
}
if(startIndex !== endIndex) {
results.push([startIndex, endIndex])
}
}
return results
}
回答1:
I'd use a regular expression: match and capture one character, then backreference that same character as many times as you can. Perform a global regex match on the string. Take all the matches and map them to an array of their index, and their index plus the length of the match:
const getRepeated = str => [...str.matchAll(/(.)\1+/g)]
.map(({ index, 0: match }) => [index, index + match.length - 1]);
const input = "hellooooloo";
const results = getRepeated(input);
console.log(results) // [(2,3), (4,7), (9,10)]
This is O(n).
The regular expression means:
(.)- Match any character, put it in a capture group\1+- Repeat the same character matched by that capture group one or more times
Eg, for the example input here, you'll get the following matches:
[
{ 0: 'll', 1: 'l', index: 2 },
{ 0: 'oooo', 1: 'o', index: 4 },
{ 0: 'oo', 1: 'o', index: 9 },
]
回答2:
You couldr educe the array of characters and check if the last character is equal to the actual and adjust the second index of the last index pair.
Otherwise check if the actual character is equal to the next character and create a new result set.
const
getRepeated = ([...array]) => array.reduce((r, c, i, a) => {
if (a[i - 1] === c) r[r.length - 1][1] = i;
else if (c === a[i + 1]) r.push([i]);
return r;
}, []),
input = 'hellooooloo',
result = getRepeated(input); // [[2, 3], [4, 7], [9, 10]]
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
来源:https://stackoverflow.com/questions/65590804/javascript-algorithms-find-starting-and-ending-indices-of-consecutively-repeate