【问题标题】:permutations of a string using iteration使用迭代的字符串排列
【发布时间】:2012-08-11 13:15:59
【问题描述】:

我正在尝试查找给定字符串的排列,但我想使用迭代。我在网上找到的递归解决方案我确实理解它,但是将其转换为迭代解决方案确实行不通。下面我附上了我的代码。非常感谢您的帮助:

public static void combString(String s) {
    char[] a = new char[s.length()];
    //String temp = "";
    for(int i = 0; i < s.length(); i++) {
        a[i] = s.charAt(i);
    }
    for(int i = 0; i < s.length(); i++) {
        String temp = "" + a[i];    

        for(int j = 0; j < s.length();j++) {
            //int k = j;
            if(i != j) {
                System.out.println(j);
                temp += s.substring(0,j) + s.substring(j+1,s.length());
            }               
        }
        System.out.println(temp);
    }
}

【问题讨论】:

  • 我真的很努力,我知道我的代码错了..无法修复它!!
  • 您想打印字符串的所有个排列吗?从问题上看不清楚。
  • 例如,如果我有一个字符串 abc...其他可能性是:abc、acb、bac、bca、cab、cba
  • 你可能想看看这个related question的答案
  • 如果这是学校或大学的课程作业,请使用家庭作业标签。

标签: java permutation


【解决方案1】:

跟进我的related question 评论,这是一个使用Counting QuickPerm Algorithm 完成您想要的Java 实现:

public static void combString(String s) {
    // Print initial string, as only the alterations will be printed later
    System.out.println(s);   
    char[] a = s.toCharArray();
    int n = a.length;
    int[] p = new int[n];  // Weight index control array initially all zeros. Of course, same size of the char array.
    int i = 1; //Upper bound index. i.e: if string is "abc" then index i could be at "c"
    while (i < n) {
        if (p[i] < i) { //if the weight index is bigger or the same it means that we have already switched between these i,j (one iteration before).
            int j = ((i % 2) == 0) ? 0 : p[i];//Lower bound index. i.e: if string is "abc" then j index will always be 0.
            swap(a, i, j);
            // Print current
            System.out.println(join(a));
            p[i]++; //Adding 1 to the specific weight that relates to the char array.
            i = 1; //if i was 2 (for example), after the swap we now need to swap for i=1
        }
        else { 
            p[i] = 0;//Weight index will be zero because one iteration before, it was 1 (for example) to indicate that char array a[i] swapped.
            i++;//i index will have the option to go forward in the char array for "longer swaps"
        }
    }
}

private static String join(char[] a) {
    StringBuilder builder = new StringBuilder();
    builder.append(a);
    return builder.toString();
}

private static void swap(char[] a, int i, int j) {
    char temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

【讨论】:

  • 如果你能想出一个更简单的解决方案,那就太复杂了。迭代比递归更复杂。
  • @DonRoby:这是一个很好的解决方案。尽管我使用示例输入对其进行了追踪,但我无法弄清楚确切的逻辑或您如何解决此问题。如果您能向我们解释您是如何解决这个问题的,那将使我们受益。谢谢。
  • 请解释逻辑@DonRoby
  • 站外链接已失效
  • @harold - 谢谢!我找到了另一个链接它的地方。
【解决方案2】:
    List<String> results = new ArrayList<String>();
    String test_str = "abcd";
    char[] chars = test_str.toCharArray();
    results.add(new String("" + chars[0]));
    for(int j=1; j<chars.length; j++) {
        char c = chars[j];
        int cur_size = results.size();
        //create new permutations combing char 'c' with each of the existing permutations
        for(int i=cur_size-1; i>=0; i--) {
            String str = results.remove(i);
            for(int l=0; l<=str.length(); l++) {
                results.add(str.substring(0,l) + c + str.substring(l));
            }
        }
    }
    System.out.println("Number of Permutations: " + results.size());
    System.out.println(results);

示例: 如果我们有 3 个字符串,例如“abc”,我们可以形成如下排列。

1) 构造一个带有第一个字符的字符串,例如'a' 并将其存储在结果中。

    char[] chars = test_str.toCharArray();
    results.add(new String("" + chars[0]));

2) 现在取字符串中的下一个字符(即“b”)并将其插入结果中先前构造的字符串的所有可能位置。由于此时我们在结果中只有一个字符串(“a”),因此这样做会为我们提供 2 个新字符串 'ba'、'ab'。在结果中插入这些新构造的字符串并删除“a”。

    for(int i=cur_size-1; i>=0; i--) {
        String str = results.remove(i);
        for(int l=0; l<=str.length(); l++) {
            results.add(str.substring(0,l) + c + str.substring(l));
        }
    }

3) 对给定字符串中的每个字符重复 2)。

for(int j=1; j<chars.length; j++) {
    char c = chars[j];
     ....
     ....
}

这给了我们来自“ba”和“cab”的“cba”、“bca”、“bac”、来自“ab”的“acb”和“abc”

【讨论】:

  • 请添加一些解释。仅代码的答案不是很有帮助。谢谢。
  • 为每个 cmets 添加了解释。
  • @Deeps 这个算法的复杂度是多少?
  • @Cyclotron3x3 您将在第一次迭代中经历 1 个大小为 1 的排列,因此创建 2(=2!)个排列,在第 2 次大小为 2 的迭代中创建 2 个排列,所以创建 6(=3!)排列,在第 3 次迭代中有 6 个大小为 3 的排列 - 所以创建 ^*4=24=4!排列..和一般k!每次迭代的排列。最后一次迭代将是大小为 n-1 的排列 - 你有 (n-1)!其中,您可以在 n 个位置添加最后一个字符 - 所以 n!最后一次迭代。所以复杂度是 O(Sum(k!) k=1..n)
  • 输入中某个字符出现多次的情况如何处理?
【解决方案3】:

工作队列允许我们为这个问题创建一个优雅的迭代解决方案。

static List<String> permutations(String string) {
    List<String> permutations = new LinkedList<>();
    Deque<WorkUnit> workQueue = new LinkedList<>(); 

    // We need to permutate the whole string and haven't done anything yet.
    workQueue.add(new WorkUnit(string, ""));

    while (!workQueue.isEmpty()) { // Do we still have any work?
        WorkUnit work = workQueue.poll();

        // Permutate each character.
        for (int i = 0; i < work.todo.length(); i++) {
            String permutation = work.done + work.todo.charAt(i);

            // Did we already build a complete permutation?
            if (permutation.length() == string.length()) {
                permutations.add(permutation);
            } else {

                // Otherwise what characters are left? 
                String stillTodo = work.todo.substring(0, i) + work.todo.substring(i + 1);
                workQueue.add(new WorkUnit(stillTodo, permutation));
            }
        }
    }
    return permutations; 
}

保存部分结果的辅助类非常简单。

/**
 * Immutable unit of work
 */
class WorkUnit {
    final String todo;
    final String done;

    WorkUnit(String todo, String done) {
        this.todo = todo;
        this.done = done;
    }
}

您可以通过将上面的代码包装在这个类中来测试它们。

import java.util.*;

public class AllPermutations {

    public static void main(String... args) {
        String str = args[0];
        System.out.println(permutations(str));
    }

    static List<String> permutations(String string) {
        ...
    }
}

class WorkUnit {
    ...
}

编译运行试试。

$ javac AllPermutations.java; java AllPermutations abcd

通过使用 LIFO 工作堆栈而不是 FIFO 队列,还可以轻松地调整以下实现以以相反的顺序返回排列列表。

【讨论】:

    【解决方案4】:
    import java.util.List;
    import java.util.Set;
    import java.util.ArrayList;
    import java.util.HashSet;
    
    public class Anagrams{
    
        public static void main(String[] args)
        {
    
            String inpString = "abcd";
            Set<String> combs = getAllCombs(inpString);
    
            for(String comb : combs)
            {
                System.out.println(comb);
            }
    
        }
    
    
        private static Set<String> getAllCombs(String inpString)
        {
            Set<String> combs = new HashSet<String>();
            if( inpString == null | inpString.isEmpty())
                return combs;
    
            combs.add(inpString.substring(0,1));
            Set<String> tempCombs = new HashSet<String>();
            for(char a : inpString.substring(1).toCharArray())
            {
                tempCombs.clear();
                tempCombs.addAll(combs);
                combs.clear();
                for(String comb : tempCombs)
                {
                    combs.addAll(getCombs(comb,a));
                }
            }
            return combs;
        }
    
        private static Set<String> getCombs(String comb, char a) {
            Set<String> combs = new HashSet<String>();
            for(int i = 0 ; i <= comb.length(); i++)
            {
                String temp = comb.substring(0, i) + a + comb.substring(i);
                combs.add(temp);
                //System.out.println(temp);
            }
            return combs;
        }   
    }
    

    【讨论】:

    • 很高兴这是您的第一篇文章。添加一些 cmets 和/或对正在发生的事情的解释.. 所以它实际上可以帮助其他人..
    【解决方案5】:

    只是发布我解决问题的方法:

    import java.util.ArrayDeque;
    import java.util.Queue;
    
    public class PermutationIterative {
        public static void main(String[] args) {
            permutationIterative("abcd");
        }
    
        private static void permutationIterative(String str) {
            Queue<String> currentQueue = null;
            int charNumber = 1;
            for (char c : str.toCharArray()) {
                if (currentQueue == null) {
                    currentQueue = new ArrayDeque<>(1);
                    currentQueue.add(String.valueOf(c));
                } else {
                    int currentQueueSize = currentQueue.size();
                    int numElements = currentQueueSize * charNumber;
                    Queue<String> nextQueue = new ArrayDeque<>(numElements);
                    for (int i = 0; i < currentQueueSize; i++) {
                        String tempString = currentQueue.remove();
                        for (int j = 0; j < charNumber; j++) {
                            int n = tempString.length();
                            nextQueue.add(tempString.substring(0, j) + c + tempString.substring(j, n));
                        }
                    }
                    currentQueue = nextQueue;
                }
                charNumber++;
            }
            System.out.println(currentQueue);
        }
    }
    

    【讨论】:

      【解决方案6】:
      package vishal villa;
      
      import java.util.Scanner;
      
      public class Permutation {
          static void result( String st, String ans)
          {
      
              if(st.length() == 0)
                  System.out.println(ans +" ");
      
              for(int i = 0; i<st.length(); i++)
              {
                  char ch = st.charAt(i);
                  String r = st.substring(0, i) +  st.substring(i + 1);
                  result(r, ans + ch);    
              }   
          }
          public static void main(String[] args) 
          {
              Scanner Sc = new Scanner(System.in);
              System.out.println("enter the string");
              String st = Sc.nextLine();
          Permutation p = new Permutation();
              p.result(st,"" );
          }
      }
      

      【讨论】:

      【解决方案7】:
      // Java program to print all permutations of a
      // given string.
      public class Permutation
      {
          public static void main(String[] args)
          {
              String str = "ABC";
              int n = str.length();
              Permutation permutation = new Permutation();
              permutation.permute(str, 0, n-1);
          }
      
          /**
           * permutation function
           * @param str string to calculate permutation for
           * @param s starting index
           * @param e end index
           */
          private void permute(String str, int s, int e)
          {
              if (s == e)
                  System.out.println(str);
              else
              {
                  for (int i = s; i <= s; i++)
                  {
                      str = swap(str,l,i);
                      permute(str, s+1, e);
                      str = swap(str,l,i);
                  }
              }
          }
      
          /**
           * Swap Characters at position
           * @param a string value
           * @param i position 1
           * @param j position 2
           * @return swapped string
           */
          public String swap(String a, int i, int j)
          {
              char temp;
              char[] charArray = a.toCharArray();
              temp = charArray[i] ;
              charArray[i] = charArray[j];
              charArray[j] = temp;
              return String.valueOf(charArray);
          }
      
      }
      

      【讨论】:

      • 请添加此代码的作用的描述,这是答案吗?
      猜你喜欢
      • 1970-01-01
      • 2018-07-14
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 2011-05-01
      • 2012-05-28
      • 2014-04-21
      相关资源
      最近更新 更多