Выполнить IndexOf более одного раза JS - PullRequest
1 голос
/ 14 июля 2020

Как найти несколько одинаковых значений и посмотреть, соответствует ли оно условиям без регулярного выражения? Предположим, что у меня есть эта строка ***6**5****8*9***2. Мне нужно проверить, содержит ли строка хотя бы три раза *** вместе, а затем, если число до и после *** составляет 11. В приведенном примере эти условия выполняются, потому что: Во-первых, в строке всего три ***, а затем 9 + 2 равно 11.

Я решил эту проблему, используя регулярное выражение, сопоставление и замену, но как я могу это сделать без применительно к этим решениям.

Я пытался сделать это без регулярного выражения, но это не сработало, потому что indexOf дает мне только один результат:

string = "***6**5****8*9***2";

  for (var i = 0; i < string.length; i++) {
     let where = (string.indexOf("***"));
     let a = parseInt(string.charAt(where - 1)); 
     let b = parseInt(string.charAt(where + 3));
    if (a + b == 11){
        isTrue = true;             
    }
   }

Ответы [ 3 ]

0 голосов
/ 14 июля 2020

Я пытался создать решение на основе вашего существующего кода:

string = "***6**5****8*9***2***4";

let where = 0;
// Skip leading *
while (where < string.length && '*' == string.charAt(where)) {
  where += 1;
}

while (true) {
  // Find three stars based on previous result
  where = string.indexOf("***", where);
  // No more triples
  if (where == -1) break;
  // Convert to digit - will be NaN if not a digit
  let a = parseInt(string.charAt(where - 1));
  // Find trailing digit
  let j = where + 1;
  // Skip to next non * char
  while (j < string.length && '*' == string.charAt(j)) {
    j += 1;
  }
  // No matches - quit
  if (j == string.length) break;
  // Parse digit
  let b = parseInt(string.charAt(j));
  // Do the math
  if (!isNaN(a) && !isNaN(b)){
    console.log(`${a} + ${b} = ${a+b}`);
  }
  where = j;
}
0 голосов
/ 14 июля 2020

Я написал простой парсер. Надеюсь, он вам поможет

string = "***6**5****8*9***2";

class Parser {
  static parse(string) {
    var lexer = new Lexer(string);
    var token = lexer.getToken();
    var prevNumberToken  = null ;
    while (token.type !== TOKEN_TYPE_END) {
      if(token.type === TOKEN_TYPE_NUMBER){
        if(prevNumberToken && prevNumberToken.value + token.value === 11 ) {
          return true;
        }
        prevNumberToken = token ;
      } else if(token.type !== TOKEN_TYPE_THREESTARS){
        prevNumberToken = null ;
      }
      token = lexer.getToken();
    }
    return false;
  }
}


class Lexer {
  constructor(string) {
    this._string = string;
    this._index = -1;
    this._len = string.length;
  }

  getToken() {
    if (this._index < 0) {
      this._index = 0;
      return new Token(TOKEN_TYPE_START, '', -1);
    }
    if (this._index >= this._len) {
      return new Token(TOKEN_TYPE_END, '', this._len);
    }
    if (this._string[this._index] === "*") {
      return this._getStarToken()
    } else {
      return this._getNumberToken();
    }
  }

  _getStarToken() {
    var stars = "";
    var i = this._index;
    while (this._index < this._len && this._string[this._index] === "*") {
      stars += "*";
      this._index++;
    }
    if (stars.length === 3) {
      return new Token(TOKEN_TYPE_THREESTARS, stars, i)
    }
    return new Token(TOKEN_TYPE_STARS, stars, i)
  }
  _getNumberToken() {
    var numbers = "";
    var i = this._index;
    while (this._index < this._len && this._string[this._index] !== "*") {
      if (this._string[this._index] >= "0" && this._string[this._index] <= "90") {
        numbers += this._string[this._index];
        this._index++;
      } else {
        throw new Error("invalid character")
      }
    }
    return new Token(TOKEN_TYPE_NUMBER, parseInt(numbers), i);
  }

}


class Token {
  constructor(type, value, index) {
    this._type = type
    this._index = index
    this._value = value
  }
  get type() { return this._type }
  get index() { return this._index }
  get value() { return this._value }
}

const TOKEN_TYPE_START = 1;
const TOKEN_TYPE_NUMBER = 2;
const TOKEN_TYPE_THREESTARS = 4;
const TOKEN_TYPE_STARS = 8;
const TOKEN_TYPE_END = 16;

console.log(Parser.parse(string));
0 голосов
/ 14 июля 2020

Вы можете разделить строку по звездочкам и сохранить начало в массиве, затем проверить, начинается ли значение со звездочки, проверить длину и левый и правый элементы на сумму.

var string = "***6**5****8*9***2",
    parts = string.split(/(\*+)/),
    result = parts.some((s, i, { [i - 1]: l, [i + 1]: r }) =>
        s[0] === '*' && s.length >= 3 && +l + +r === 11
    );

console.log(result);
console.log(parts);
...