Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Calculadora

0

47
Vistas
RegEx via Javascript

I do not know how to solve this coding puzzle with Javascript. I've never been working with Regular Expressions but I feel they are the best approach to solve it.

Let's say, I have this code:

let str = "abcdefabc";
let pattern = "abc";

What I need is to write the algorithm, that returns the array of arrays (two-dimensional) of indexes like this:

[ 
[1, 2, 3], 
[4, 5, 6], 
[7, 8, 9] 
] 

where indexes are the positions of pattern letters in str. For example, with str = 'abcdefabc' and pattern pattern = 'abc' algo must return such arrays:

  1. [0, 1, 2] (first 'abc' inside str that matches pattern: "abcdefabc");
  2. [6, 7, 8] (last 'abc' inside str that matches pattern: "abcdefabc"); these are obvious examples, but it must return those as well:
  3. [0, 1, 8] because "abcdefabc"
  4. [0, 7, 8] because "abcdefabc"

I hope you got the logic. The order of pattern is important: str = 'fox1423423man_united_x' with pattern ='fox' must return [[0, 1, 2], [0, 1, 21]];

str = 'google with pattern ='fox' must return null because there is no 'fox' somewhere in between;

str = 'xof' with pattern ='fox' must return null because the way the letters go is important;

All strings will be lower-case

7 months ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

I think this is a reasonably clean implementation, based on a simple function that finds all indices of a character in a string (or actually, more generally, all indices of a value in an iterable).

const allIndices = (xs, t, s = 0) => 
  [...xs] .slice (s) .flatMap ((x, i) => x == t ? [i] : [])

const allMatches = (word, sub, i = 0) => 
  sub .length == 0
    ? [[]]
    : allIndices (word, sub [0], i) 
        .flatMap (j => allMatches (word, sub .slice (1), i + j + 1) .map (s => [i + j, ...s]))

console .log (allMatches ("abcdefabc", "abc"))
console .log (allMatches ("fox1423423man_united_x", "fox"))
.as-console-wrapper {max-height: 100% !important; top: 0}

allIndices uses flatMap as a sort of filter that returns indices rather than values.

allMatches calls allIndices with the first character of the search string, and then recurs on the remainder of the word and the other character of the search string, combining the current index with those results. It bottoms out when the search string is empty and returns a result containing just an empty array.

We could write a version with less index fiddling, but it would then need to slice and dice the main string much more often.

7 months ago · Juan Pablo Isaza Denunciar

0

Here's a solution that solves it via recursion.
It uses the indexOf method to find the positions of the characters.

function findTokenPositions(str, tokens) {
  let arr = [];
  function recurse (strpos=0, tok=0, accum=[]) {
    if (tok >= tokens.length) { arr.push(accum); return; }
    strpos = str.indexOf(tokens[tok], strpos);
    if (strpos < 0) { return; }
    accum[tok] = strpos;
    recurse(strpos+1, tok+1, [...accum])
    recurse(strpos+1, tok,   [...accum]);
  }
  recurse();
  return arr;
}

let tests = [ 
  ["abcdefabc", "abc"], 
  ["fox1423423man_united_x", "fox"], 
  ["hound", "fox"], 
  ["xof", "fox"]
];

tests.forEach(x => {
  console.log(x[0]+' : '+x[1]+' --> ' + JSON.stringify(findTokenPositions(x[0], x[1])))
});

And here's another function that uses regex to get the positions.
This only scans the string once.

function getTokenPositions(str, tokens) {
  let positions = []; let base = []; let m;
  let re = new RegExp('['+tokens+']','gi');
  while (m = re.exec(str)) { 
    positions.push([m[0], m.index])
    if(m[0] === tokens[0]) { base.push([m.index]); }
  }
  for (let tok=1; tok < tokens.length; tok++) {
    let arr = [];
    for (let i=0; i < positions.length; i++) {
      if (positions[i][0] === tokens[tok]) {
        let tmp = [...base];
        for (let j=0; j < tmp.length; j++) {      
          tmp[j][tok] = positions[i][1];
        }
        tmp.forEach(a=>arr.push([...a]));
      }
    }
    base = [...arr];
  }
  // only return the sorted
  return base.filter(x => x.every((v,i)=>(i===0||v>=x[i-1])));
}

let tests = [ 
  ["abcdefabc", "abc"], 
  ["fox1423423man_united_x", "fox"], 
  ["hound", "fox"], 
  ["xof", "fox"]
];

tests.forEach(x => {
  console.log(x[0]+' : '+x[1]+' --> ' + JSON.stringify(getTokenPositions(x[0], x[1])))
});

7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar empleo Planes Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2023 PeakU Inc. All Rights Reserved.