递归打印字符串的所有排列(Javascript)

递归打印字符串的所有排列(Javascript),javascript,string,algorithm,recursion,permutation,Javascript,String,Algorithm,Recursion,Permutation,我在其他语言中见过这个问题的版本,但在JS中没有 是否可以在一个函数中递归执行此操作 我知道我需要获取字符串中的第一个元素,然后将其附加到字符串其余部分的递归的每个解决方案中。 所以从逻辑上讲,我理解递归需要如何进行。我只是不明白如何将第一个字符附加到每个递归解决方案上 var myString = "xyz"; function printPermut(inputString){ var outputString; if(inputString.length === 0){

我在其他语言中见过这个问题的版本,但在JS中没有

是否可以在一个函数中递归执行此操作

我知道我需要获取字符串中的第一个元素,然后将其附加到字符串其余部分的递归的每个解决方案中。 所以从逻辑上讲,我理解递归需要如何进行。我只是不明白如何将第一个字符附加到每个递归解决方案上

var myString = "xyz";

function printPermut(inputString){
    var outputString;
    if(inputString.length === 0){
        return inputString;
    }
    if(inputString.length === 1){
        return inputString;
    }
    else{
       for(int i = 0; i<inputString.length(); i++){
           //something here like: 
           //outputString = outputString.concat(printPermut(inputString.slice(1))??
           //maybe store each unique permutation to an array or something?
       } 
    }
}
var myString=“xyz”;
函数printPermut(inputString){
变量输出字符串;
如果(inputString.length==0){
返回输入字符串;
}
如果(inputString.length==1){
返回输入字符串;
}
否则{

对于(int i=0;i让我们编写一个函数,将字符串的所有排列作为数组返回。由于您不需要任何全局变量,因此返回排列是至关重要的

  function permut(string) {
  if (string.length < 2) return string; // This is our break condition

  var permutations = []; // This array will hold our permutations
  for (var i = 0; i < string.length; i++) {
    var char = string[i];

    // Cause we don't want any duplicates:
    if (string.indexOf(char) != i) // if char was used already
      continue; // skip it this time

    var remainingString = string.slice(0, i) + string.slice(i + 1, string.length); //Note: you can concat Strings via '+' in JS

    for (var subPermutation of permut(remainingString))
      permutations.push(char + subPermutation)
  }
  return permutations;
}

希望我能帮你解决你的问题。

排列问题已经被研究到了极点。这是一个众所周知的解决方案。下面是一个JS版本,使用生成器:

函数*permute(a,n=a.length){
if(n perm.join(“”))

.filter((el,idx,self)=>(self.indexOf(el)==idx));
使用递归函数迭代字符串


函数getPermutations(字符串){
var结果=[];
if(string.length==1)
{
结果:推(串);
返回结果;
}
对于(变量i=0;i(self.indexOf(el)==idx));
log(“总排列:+permutation.length”);
console.log(排列);
半离题主题:

给定字符串的随机排列与rndperm一样简单:

i=document.getElementById(“word”);
b=document.getElementById(“butt”);
rndperm=(z)=>{
返回z.split(“”).sort(()=>((Math.random()*3)>>0)-1.join(“”)
}
函数加扰(){
i、 数值=rndperm(即数值);
}
var z;
函数sci(){
如果(z!=未定义){
净距(z);
b、 innerText=“加扰”;
z=未定义;
}否则{
z=设置间隔(加扰,100);
b、 innerText=“正在运行…”;
}
}

Scramble
问题分类:您可以将此问题视为一个探索问题,即给定一组输入字符,探索您可以排列它们的不同方式

解决方案:算法擅长解决探索性问题,尽管它具有很高的时间复杂度。要演示解决方案,请想象您将如何用一小部分输入字符手动解决此问题:[a,b,c]

以下是步骤:

  • 取最左边的字符。这是索引0处的字符,并与索引0处的目标右字符交换,即与自身交换。这是因为[a,b,c]本身是一个有效的排列,因此我们希望保留它。交换字符通常需要两个指向每个字符的指针。因此,假设我们将有一个指针
  • 使用相同的最左侧字符(在索引0处)与索引0+1=1处的目标右侧字符进行交换,即将目标右侧指针再移动一步。这将为您提供输出:[b,a,c]
  • 使用相同的最左侧字符(索引0处)与下一个目标右侧字符(即索引0+1+1=2)进行交换。这将为您提供输出:[c,b,a]
  • 好的,现在我们需要停止,因为没有更多的目标右字符可以与最左边的字符交换。因此,我们的指针需要保持小于输入中的最大索引。一次移动指针一步,我们可以使用启动fr的for循环从左侧的索引开始,以输入长度-1结束

  • 现在,您需要从上面执行完全相同的步骤,但移动左指针,使其指向下一个最左边的字符。但是,保留步骤2和3中的输入。另一种想象这种情况的方法是说:“嘿,我已经完成了最左边的字符。现在我不想再使用它,但我希望继续使用t他在我目前为止的成绩中排名第二

  • 什么时候停止?当左指针达到输入字符串-1的长度时,因为该索引后没有更多字符。在递归算法中(例如回溯),需要停止的情况称为base case。在我们的示例中,基本情况是:left==input.length-1

  • 这是一个图形化的可视化:

    left index|                         Input String:
    -------------------------------------------------------------------------------
    
    left = 0  |                                                              in=[a, b, c]
    
                        (swap in[0] with in[0])                         (swap in[0] with in[1])                         (swap in[0] with in[2])
    left = 1  |               in=[a, b, c]                                   in=[b, a, c]                                      in=[c, b, a]
    
                (swap in[1] with in[1]) (swap in[1] with in[2]) (swap in[1] with in[1])(swap in[1] with in[2])  (swap in[1] with in[1])(swap in[1] with in[2])
    left = 2  | [a, b, c]                   [a, c, b]               [b, a, c]               [b, c, a]                   [c, b, a]           [c, a, b]
    
    摘要:

    • 要将指针向左移动,我们将使用递归增量
    • 要将指针向右移动,我们将使用for循环,但是我们需要始终从左指针开始,否则我们将探索我们已经探索过的内容
    回溯: 回溯算法的伪代码采用以下形式:

    fun(input)
        if(base_case_check(input)) {
            //do final step
        } else {
            //choose
            fun(reduce(input)) //explore
            //un-choose
        }
    
    我们的解决方案:

    函数置换(字符串){
    如果(!string | | string.length==0)
    返回新集合(['']);
    设左=0;
    让结果=新集合();
    排列助手(字符串、结果、左侧);
    返回结果;
    }
    函数置换助手(字符串,r
    
    fun(input)
        if(base_case_check(input)) {
            //do final step
        } else {
            //choose
            fun(reduce(input)) //explore
            //un-choose
        }
    
    permutation=(str,prefix)=>{
       if(str.length==0){
          console.log(prefix);
       }
       else{
          for(let i=0;i<str.length;i++){
              let rem = str.substring(0,i)+str.substring(i+1);
              permutation(rem,prefix+str[i]);
           }
        }
     }
     let str="ABC";
     permutation(str,"");
    
    const str_Permutations = (str,ar = []) => {
      str = `${str}`; // ensure type **String**
      if(ar.indexOf(str)>-1 || str.length !== (ar.strlen || str.length)) return false; // Checking if value is alreay there or(||) on recursive call string length should not be provided string 
      ar.strlen = ar.strlen || str.length; // Setting str length of provided value(string)
      ar.push(str);    // Pushing to array
      for(let i = 0; i<str.length;i++){
        str_Permutations(str[i] + str.split('').filter(v=>v!==str[i]).join(''),ar);
      }
      return Array.from(ar); // Removing *strlen* from main result and return **Result** as array
    }
    str_Permutations("ABC")
    
    //Result: (6) ["ABC", "BAC", "CBA", "BCA", "ACB", "CAB"]