生成字符串的所有辅音

时间:2018-09-25 19:58:42

标签: javascript algorithm

我想生成给定字符串的所有辅音。

  

和声是一种通过重复识别的文体文学手段   元音相邻单词中相同或相似辅音的组合   声音不同。 (Wikipedia

consonant是表示辅音的字母。 下表将各组英语辅音同化,采用以下便利来使事情保持简单(istic):

  1. 它忽略图(“ sh”,“ ch”,“ th”等)。
  2. 它忽略元音。
  3. 它会忽略“ h”,“ y”,“ w”,“ x”。
  4. 假定给定字母只能是一个辅音组的成员。因此,“ c”与“ s”和“ z”(随机)放在一起,而“ g”与“ j”放在一起。

我们还假设允许输入符合情况2和3的输入,并且应该将其忽略。但是,如果输入符合情况1或破坏情况4(请参见下面的示例),则该输入无效。

所以:

var consonants = [
    ['b', 'p'],
    ['c', 's', 'z'],
    ['d', 't'],
    ['f', 'v'],
    ['g', 'j'],
    ['k', 'q']
]; 

例如,给定字符串"jedi",输出应为:

var consonances = ["gedi", "jeti", "geti"]

请注意,“ v”字样(第2种情况)的“ e”和“ i”是允许输入的。

其他一些示例:

"btb"       --> ["ptb", "pdb", "pdp", "bdb", "bdp", "btp", "ptp"]
"star"      --> ["ctar", "ztar", "sdar", "cdar", "zdar"]

无效输入:

  1. 有向图:"show", "chair", "high", "the"
  2. 破例4:"sure", "cat", "good"

我正在努力寻找解决方法。我经历了排列问题,因为我猜想它们可能与这里有关,但是我看不到如何在这里应用这样的解决方案。

我需要一个算法,但是完整的代码解决方案当然是不错的。 我将在此处添加剩下的(JS代码):

const irrelvant = ['a', 'e', 'i', 'o', 'u', 'h', 'y', 'w', 'x'];
function isConsonant(c) {
   return !irrelvant.includes(c);
}
function getConsonants(c) {
   let curConsonants = [];
   consonants.every((group) => {
      if (group.includes(c)) {
         curConsonants = group;
      };
      return !curConsonants.length;
   });
   return curConsonants;
}

3 个答案:

答案 0 :(得分:1)

我建议在地图中整理相关辅音:

var consonants = {
  "b": "p",
  "p": "b",
  "c": "sz",
  "s": "cz",
  "z": "cs",
  "d": "t",
  "t": "d",
  "f": "v",
  "v": "f",
  "g": "j",
  "j": "g",
  "k": "q",
  "q": "k", 
]; 

现在,您可以按char迭代字符串char。如果您在地图中命中了一个字符,请考虑已更改的单词,并在pos中插入映射字符串中的每个字符(除了您仍然要做的不变的递归)。伪代码:

function generate(word, pos) {
   if (pos == word.length) {
     console.log(word);
     return;
   }
   generate(word, pos + 1);
   mapped = consonants[word.charAt(pos)];
   if (mapped != null) {
     var prefix = word.substring(0, pos);
     var suffix = word.substring(pos + 2);
     for (var i = 0; i < mapped.length; i++) {
       var changed =  prefix + mapped.charAt(i) + suffix; 
       geneate(changed, pos + 1);
     }
   }
 }

答案 1 :(得分:1)

我可以给您一个简单的算法,如何使用递归算法在python中完成。

xcopy "C:\Temp\123.cfg" C:\users\%username%\AppData\Roaming\Mozilla\Firefox\Profiles\*.default" /d /y

输出:

import itertools

consonants = [['b', 'p'],
    ['c', 's', 'z'],
    ['d', 't'],
    ['f', 'v'],
    ['g', 'j'],
    ['k', 'q']]

# Create a map to indicate which group can the letter be found in
sound = {} # These are actually index of groups for letters
for i,a_group in enumerate(consonants):
    for letter in a_group:
        sound[letter] = i # b, p have the sound 0, c,s,z have sound 1 etc

def getConsonantsRec(c, options):
    if len(c) > 0:
        if c[0] in sound:
            options.append(consonants[sound[c[0]]]) # Add all letters as the option at this place
        else:
            options.append([c[0]]) #Only this letter at this place
        getConsonantsRec(c[1:],options) #Make string shorter each call
    return

def getConsonants(c):
    options = []
    getConsonantsRec(c,options)
    return [x for x in itertools.product(*options)] #Generate the combinations from the options at each place

allConsonants = getConsonants('star')
print(allConsonants)

现在,您可以通过添加对字形图,元音等的检查来进一步增强此功能。

答案 2 :(得分:0)

其他解决方案帮助我节省了几分钱:那是一个简单的笛卡尔积问题。选择适合您需求的implementation,您就完成了。例如:

console.log(...getConsonances('stars').map(con => con.join('')));

function getConsonances(s) {
    let combConsonants = [];
    let idx = 0;
    s.split('').forEach((c) => {
       const curConsonants = getConsonants(c);
       if (curConsonants.length) {
           combConsonants.push(curConsonants);
           idx++;
       } else {
           let notConsonant = [combConsonants[idx] ? combConsonants[idx] : [], c].join('');
           combConsonants.splice(idx, 1, [notConsonant]); 
       }
    }); 
    return cartesianProduct(combConsonants);
}
function getConsonants(c) {
   const consonants = [
    ['b', 'p'],
    ['c', 's', 'z'],
    ['d', 't'],
    ['f', 'v'],
    ['g', 'j'],
    ['k', 'q']
]; 
   let curConsonants = [];
   consonants.every((group) => {
      if (group.includes(c)) {
         curConsonants = group;
      };
      return !curConsonants.length;
   });
   return curConsonants;
}
function cartesianProduct(arr) {
  return arr.reduce((a, b) =>
    a.map(x => b.map(y => x.concat(y)))
    .reduce((a, b) => a.concat(b), []), [[]]);
}