Попытка заставить рекурсивные перестановки функционировать, используя диакритические знаки в JavaScript - PullRequest
0 голосов
/ 21 мая 2018

Мне удалось написать простую функцию, которая принимает входную строку и сравнивает каждый символ с объектом словаря, содержащим диакритические (акцентированные) символы в паре с их недиакритическими символами, а затем пытается создать новую строку для каждой перестановкииз этого.

Однако, это только полуфункциональный.Когда я ввожу строку «hello world», она выглядит так:

["hèllo world", "héllo world", "hêllo world", "hëllo world", "hēllo world", 
"hėllo world", "hęllo world", "hellô world", "hellö world", "hellò world", 
"helló world", "hellō world", "hellõ world", "hello wôrld", "hello wörld", 
"hello wòrld", "hello wórld", "hello wōrld", "hello wõrld"]

или, если я ввожу «некоторую строку», получается:

["śome string", "šome string", "sôme string", "söme string", "sòme string", 
"sóme string", "sōme string", "sõme string", "somè string", "somé string", 
"somê string", "somë string", "somē string", "somė string", "somę string", 
"some śtring", "some štring", "some strîng", "some strïng", "some stríng", 
"some strīng", "some strįng", "some strìng", "some striñg", "some strińg"]

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

Как мне повторить итерацию для каждого из этих элементов массива, чтобы найти каждую возможную комбинацию из них?Вместо того, чтобы переходить к следующему символу и оставлять те же, что и исходная строка ввода.Мне нужно, чтобы он имел каждую перестановку.

Я не спал всю ночь, пытаясь понять это, и хотя я добился определенного прогресса, я все еще застрял.Я попытался создать рекурсивную функцию, вызывающую себя изнутри себя, но это просто сломало мой браузер.

Любая помощь будет удивительной :)

вот код, который я написал:

function jig(inputStr) {
  const accents = {
    a: ["à", "á", "â", "ä", "ã", "å", "ā"],
    c: ["ç", "ć", "č"],
    e: ["è", "é", "ê", "ë", "ē", "ė", "ę"],
    i: ["î", "ï", "í", "ī", "į", "ì"],
    n: ["ñ", "ń"],
    o: ["ô", "ö", "ò", "ó", "ō", "õ"],
    s: ["ś", "š"],
    u: ["û", "ü", "ù", "ú", "ū"],
    y: ["ÿ"],
    z: ["ž", "ź", "ż"]
  };

  function hasAccents(char) {
    return /[aceinosuyz]/.test(char);
  }

  var results = [];

  for (var i = 0; i < inputStr.length; i++) {
    var currentChar = inputStr.substr(i, 1);
    // console.log(currentChar);
    if (hasAccents(currentChar)) {
      // console.log(accents[currentChar]);

      for (var y = 0; y < accents[currentChar].length; y++) {
        var tempArray = inputStr.split("");

        tempArray[i] = accents[currentChar][y];
        results.push(tempArray.join(""));
        //jig(tempArray.join(""));
      }
    }
  }

  return results;
}

1 Ответ

0 голосов
/ 21 мая 2018

Вот метод, который строит каждую строку.Когда встречается символ-кандидат для акцентов, мы помещаем в стек каждую версию строки до этого символа.

Код JavaScript:

function f(s){
  const accents = {
    a: ["à", "á", "â", "ä", "ã", "å", "ā"],
    c: ["ç", "ć", "č"],
    e: ["è", "é", "ê", "ë", "ē", "ė", "ę"],
    i: ["î", "ï", "í", "ī", "į", "ì"],
    n: ["ñ", "ń"],
    o: ["ô", "ö", "ò", "ó", "ō", "õ"],
    s: ["ś", "š"],
    u: ["û", "ü", "ù", "ú", "ū"],
    y: ["ÿ"],
    z: ["ž", "ź", "ż"]
  };
  
  var result = [];
  
  var stack = [['', 0]];
  
  while (stack.length){
    let [str, i] = stack.pop();
    
    if (i == s.length){
      result.push(str);
      continue;
    }
    
    if (accents[s[i]]){
      for (let j=0; j<accents[s[i]].length; j++)
        stack.push([str + accents[s[i]][j], i + 1]);
    }

    stack.push([str + s[i], i + 1]);
  }
  
  return result;
}

console.log(f('hello'));
...