在java中生成无重复/置换的变体

在java中生成无重复/置换的变体,java,algorithm,permutation,variations,Java,Algorithm,Permutation,Variations,我必须生成所有的变化,不重复数字0-9 它们的长度可以是1到10。我真的不知道如何解决它,尤其是如何避免重复 例如: 变异长度:4 随机变异:9856875312431234等(但不是9985-包含重复) 如果有人能帮我解决这个问题,特别是提供一些代码和线索,我将不胜感激。要寻找的关键词是排列。有大量免费提供的源代码可以执行它们 至于保持它不重复,我建议使用一种简单的递归方法:对于每个数字,您可以选择是否将其纳入变体中,因此您的递归通过数字计数,并分叉为两个递归调用,一个包含数字,另一个不包含数

我必须生成所有的变化,不重复数字0-9

它们的长度可以是1到10。我真的不知道如何解决它,尤其是如何避免重复

例如: 变异长度:4 随机变异:9856875312431234等(但不是9985-包含重复)


如果有人能帮我解决这个问题,特别是提供一些代码和线索,我将不胜感激。

要寻找的关键词是排列。有大量免费提供的源代码可以执行它们

至于保持它不重复,我建议使用一种简单的递归方法:对于每个数字,您可以选择是否将其纳入变体中,因此您的递归通过数字计数,并分叉为两个递归调用,一个包含数字,另一个不包含数字。然后,在到达最后一个数字后,每个递归本质上会给出一个(唯一的、排序的)无重复数字列表。然后,您可以创建此列表的所有可能排列,并组合所有这些排列以获得最终结果

(和达菲莫说的一样:我不会提供代码)


高级说明:递归基于0/1(排除、包含),可以直接转换为位,因此是整数。因此,为了获得所有可能的数字组合而不实际执行递归本身,您可以简单地使用所有10位整数并对它们进行迭代。然后解释数字,使设置的位对应于列表中需要排列的数字。

想象你有一个神奇的功能-给定一个数字数组,它将返回正确的排列

您如何使用该函数生成一个新的排列列表,其中只包含一个额外的数字

e、 g

如果我给了你一个名为
permute\u three(char[3]digits)
,我告诉你它只对数字
0
1
2
,使用给定的
permute\u three
函数,你怎么能编写一个可以置换
0
1
2
3
的函数呢

一旦你解决了这个问题,你注意到了什么?你能概括一下吗

使用它很简单:

@Test
public void generatePermutations() {
    // digits is the string "0123456789"
    String digits = $('0', '9').join();

    // then generate 10 permutations
    for (int i : $(10)) {
        // shuffle, the cut (0, 4) in order to get a 4-char permutation
        System.out.println($(digits).shuffle().slice(4));
    }
}

此代码类似于没有重复的代码,添加了if-else语句。请检查此项

在上面的代码中,编辑for循环,如下所示

for (j = i; j <= n; j++)
{

if(a[i]!=a[j] && !is_duplicate(a,i,j))              
    {
        swap((a+i), (a+j));
        permute(a, i+1, n);
        swap((a+i), (a+j)); 
    }
    else if(i!=j)  {}  // if no duplicate is present , do nothing           
    else permute(a,i+1,n);  // skip the ith character
}

bool is_duplicate(int *a,int i,int j) 
{
     if a[i] is present between a[j]...a[i] 
        return 1;
    otherwise
        return 0;

}

for(j=i;j这是我的Java代码。如果您不理解,请随时询问。这里的要点是:

  • 再次对字符数组排序。例如:a1 a2 a3 b1 b2 b3…(a1=a2=a3)
  • 生成置换并始终保持条件:a1的索引
    导入java.util.array;
    公共类置换DUP{
    公共无效置换(字符串s){
    char[]original=s.toCharArray();
    数组。排序(原始);
    char[]clone=新字符[s.length()];
    boolean[]标记=新的boolean[s.length()];
    数组。填充(标记,假);
    排列(原始、克隆、标记、0、s.length());
    }
    私有void置换(字符[]原始,字符[]克隆,布尔[]标记,整数长度,整数n){
    如果(长度==n){
    System.out.println(克隆);
    返回;
    }
    对于(int i=0;i0&&原始[i]==原始[i-1]&&标记[i-1]==假)继续;
    标记[i]=真;
    克隆[长度]=原始[i];
    排列(原始、克隆、标记、长度+1,n);
    标记[i]=假;
    }
    }
    公共静态void main(字符串[]args){
    置换dup p=新的置换dup();
    p、 置换(“abcab”);
    }
    }
    
    无重复排列是基于一个定理,即结果的数量是元素计数(在本例中为数字)的阶乘。在您的例子中,10!是10*9*8*7*6*5*4*3*2*1=3628800。它完全正确的证明也是生成的正确解决方案。 那么如何呢?在第一个位置,即从左边开始,你可以有10个数字,在第二个位置,你只能有9个数字,因为一个数字在左边的位置,我们不能重复相同的数字等等(证明是通过数学归纳法完成的)。 那么,如何生成前十个结果呢?据我所知,最简单的方法是使用循环移位。它意味着数字在一个位置向左移动的顺序(如果你愿意,也可以向右移动),以及溢出的数字放在空白处的顺序。 这意味着前十个结果:

    10987654321
    9876542210
    8765432109
    76542321098
    65432110987
    543210109876

    第一行是基本样本,因此最好在生成之前将其放入集合中。优点是,在下一步中,您必须解决相同的问题,以避免不必要的重复

    在下一步中,递归地只旋转10-1个数字10-1次,以此类推。 这意味着对于第二步中的前9个结果:

    10987654321
    1087654219
    10765432198
    106542321987
    10543219876

    请注意,前一步中出现了第一行,所以不能再将其添加到生成的集合中

    算法递归地执行上述操作。可以为10!生成所有3628800个组合,因为嵌套的数量与数组中的元素数量相同(这意味着在您的情况下,10个数字在我的计算机上停留大约5分钟)若你们想在数组中保留所有的组合,你们需要有足够的内存

    有解决办法

    package permutation;
    
    /** Class for generation amount of combinations (factorial)
     * !!! this is generate proper permutations without repeating and proper amount (počet) of rows !!!
     *
     * @author hariprasad
     */
    public class TestForPermutationII {
      private static final String BUMPER = "*";
      private static int counter = 0;
      private static int sumsum = 0;
      // definitoin of array for generation
      //int[] testsimple = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
      int[] testsimple = {1, 2, 3, 4, 5};
      private int ELEMNUM = testsimple.length;
      int[][] shuff;
    
      private String gaps(int len) {
        String addGap = "";
        for(int i=0; i <len; i++)
          addGap += "  ";
        return addGap;
      }
    
      /** Factorial computing */
      private int fact(int num) {
        if (num > 1) {
          return num * fact(num - 1);
        } else {
          return 1;
        }
      }
    
      /** Cyclic shift position to the left */  
      private int[] lShiftPos(int[] arr, int pos) {
        int[] work = new int[ELEMNUM];
        int offset = -1;
        for (int jj = 0; jj < arr.length; jj++) {
          if (jj < pos) {
            work[jj] = arr[jj];
          } else if (jj <= arr.length - 1) {
            if (jj == pos) {
              offset = arr[pos]; // last element
            }
            if (jj != (arr.length - 1)) {
              work[jj] = arr[jj + 1];
            } else {
              work[jj] = offset;
            }
          }
        }
        return work;
      }
    
      private String printBuff(int[] buffer) {
        String res = "";
        for (int i= 0; i < buffer.length; i++) {
          if (i == 0) 
            res += buffer[i];
          else
            res += ", " + buffer[i];
        }
        return res;
      };
    
      /** Recursive generator for arbitrary length of array */
      private String permutationGenerator(int pos, int level) {
        String ret = BUMPER;
        int templen = counter;
        int[] work = new int[ELEMNUM];
        int locsumread = 0;
        int locsumnew = 0;
        //System.out.println("\nCalled level: " + level);
    
        for (int i = 0; i <= templen; i++) {
          work = shuff[i];
          sumsum++;
          locsumread++;
          for (int ii = 0; ii < pos; ii++) {
            counter++;
            sumsum++;
            locsumnew++;
            work = lShiftPos(work, level); // deep copy
            shuff[counter] = work;
          }
        }
    
        System.out.println("locsumread, locsumnew: " + locsumread + ", " + locsumnew);
        // if level == ELEMNUM-2, it means no another shift
        if (level < ELEMNUM-2) {
          ret = permutationGenerator(pos-1, level+1);
          ret = "Level " + level + " end.";
          //System.out.println(ret);
        }
        return ret;
      }
    
      public static void main(String[] argv) {
        TestForPermutationII test = new TestForPermutationII();
        counter = 0;
        int len = test.testsimple.length;
        int[] work = new int[len];
    
        test.shuff = new int[test.fact(len)][];
    
        //initial
        test.shuff[counter] = test.testsimple;
        work = test.testsimple; // shalow copy
    
        test.shuff = new int[test.fact(len)][];
        counter = 0;
        test.shuff[counter] = test.testsimple;
        test.permutationGenerator(len-1, 0);
    
        for (int i = 0; i <= counter; i++) {
          System.out.println(test.printBuff(test.shuff[i]));
        }
    
        System.out.println("Counter, cycles: " + counter + ", " + sumsum);
      }
    }
    
    包置换;
    /**梳的生成量的类
    
    package permutation;
    
    /** Class for generation amount of combinations (factorial)
     * !!! this is generate proper permutations without repeating and proper amount (počet) of rows !!!
     *
     * @author hariprasad
     */
    public class TestForPermutationII {
      private static final String BUMPER = "*";
      private static int counter = 0;
      private static int sumsum = 0;
      // definitoin of array for generation
      //int[] testsimple = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
      int[] testsimple = {1, 2, 3, 4, 5};
      private int ELEMNUM = testsimple.length;
      int[][] shuff;
    
      private String gaps(int len) {
        String addGap = "";
        for(int i=0; i <len; i++)
          addGap += "  ";
        return addGap;
      }
    
      /** Factorial computing */
      private int fact(int num) {
        if (num > 1) {
          return num * fact(num - 1);
        } else {
          return 1;
        }
      }
    
      /** Cyclic shift position to the left */  
      private int[] lShiftPos(int[] arr, int pos) {
        int[] work = new int[ELEMNUM];
        int offset = -1;
        for (int jj = 0; jj < arr.length; jj++) {
          if (jj < pos) {
            work[jj] = arr[jj];
          } else if (jj <= arr.length - 1) {
            if (jj == pos) {
              offset = arr[pos]; // last element
            }
            if (jj != (arr.length - 1)) {
              work[jj] = arr[jj + 1];
            } else {
              work[jj] = offset;
            }
          }
        }
        return work;
      }
    
      private String printBuff(int[] buffer) {
        String res = "";
        for (int i= 0; i < buffer.length; i++) {
          if (i == 0) 
            res += buffer[i];
          else
            res += ", " + buffer[i];
        }
        return res;
      };
    
      /** Recursive generator for arbitrary length of array */
      private String permutationGenerator(int pos, int level) {
        String ret = BUMPER;
        int templen = counter;
        int[] work = new int[ELEMNUM];
        int locsumread = 0;
        int locsumnew = 0;
        //System.out.println("\nCalled level: " + level);
    
        for (int i = 0; i <= templen; i++) {
          work = shuff[i];
          sumsum++;
          locsumread++;
          for (int ii = 0; ii < pos; ii++) {
            counter++;
            sumsum++;
            locsumnew++;
            work = lShiftPos(work, level); // deep copy
            shuff[counter] = work;
          }
        }
    
        System.out.println("locsumread, locsumnew: " + locsumread + ", " + locsumnew);
        // if level == ELEMNUM-2, it means no another shift
        if (level < ELEMNUM-2) {
          ret = permutationGenerator(pos-1, level+1);
          ret = "Level " + level + " end.";
          //System.out.println(ret);
        }
        return ret;
      }
    
      public static void main(String[] argv) {
        TestForPermutationII test = new TestForPermutationII();
        counter = 0;
        int len = test.testsimple.length;
        int[] work = new int[len];
    
        test.shuff = new int[test.fact(len)][];
    
        //initial
        test.shuff[counter] = test.testsimple;
        work = test.testsimple; // shalow copy
    
        test.shuff = new int[test.fact(len)][];
        counter = 0;
        test.shuff[counter] = test.testsimple;
        test.permutationGenerator(len-1, 0);
    
        for (int i = 0; i <= counter; i++) {
          System.out.println(test.printBuff(test.shuff[i]));
        }
    
        System.out.println("Counter, cycles: " + counter + ", " + sumsum);
      }
    }
    
        package permutations;
    
    import java.util.HashSet;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    
    /**
     * @author Vladimir Hajek
     *
     */
    public class PermutationSimple {
        private static final int MAX_NUMBER = 3;
    
        Set<String> results = new HashSet<>(0);
    
        /**
         * 
         */
        public PermutationSimple() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @param availableNumbers
         * @return
         */
        public static List<String> generatePermutations(Set<Integer> availableNumbers) {
            List<String> permutations = new LinkedList<>();
    
            for (Integer number : availableNumbers) {
                Set<Integer> numbers = new HashSet<>(availableNumbers);
                numbers.remove(number);
    
                if (!numbers.isEmpty()) {
                    List<String> childPermutations = generatePermutations(numbers);
                    for (String childPermutation : childPermutations) {
                        String permutation = number + childPermutation;
                        permutations.add(permutation);
                    }
                } else {
                    permutations.add(number.toString());
                }
            }
    
            return permutations;
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            Set<Integer> availableNumbers = new HashSet<>(0);
    
            for (int i = 1; i <= MAX_NUMBER; i++) {
                availableNumbers.add(i);
            }
    
            List<String> permutations = generatePermutations(availableNumbers);
            for (String permutation : permutations) {
                System.out.println(permutation);
            }
    
        }
    }
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    public class Permutations {
    
        public static <T> Collection<List<T>> generatePermutationsNoRepetition(Set<T> availableNumbers) {
            Collection<List<T>> permutations = new HashSet<>();
    
            for (T number : availableNumbers) {
                Set<T> numbers = new HashSet<>(availableNumbers);
                numbers.remove(number);
    
                if (!numbers.isEmpty()) {
                    Collection<List<T>> childPermutations = generatePermutationsNoRepetition(numbers);
                    for (List<T> childPermutation : childPermutations) {
                        List<T> permutation = new ArrayList<>();
                        permutation.add(number);
                        permutation.addAll(childPermutation);
                        permutations.add(permutation);
                    }
                } else {
                    List<T> permutation = new ArrayList<>();
                    permutation.add(number);
                    permutations.add(permutation);
                }
            }
    
            return permutations;
        }
    }
    
    def find(alphabet, alpha_current, str, str_current, max_length, acc):
      
      if (str_current == max_length):
        acc.append(''.join(str))
        return
      
      for i in range(alpha_current, len(alphabet)):
        str[str_current] = alphabet[i]
        
        alphabet[i], alphabet[alpha_current] = alphabet[alpha_current], alphabet[i]
        
        find(alphabet, alpha_current+1, str, str_current+1, max_length, acc)
        
        alphabet[i], alphabet[alpha_current] = alphabet[alpha_current], alphabet[i]
      
      return
    
    max_length = 4
    str = [' ' for i in range(max_length)]
    acc = list()
    find(list('absdef'), 0, str, 0, max_length, acc)
    
    for i in range(len(acc)):
      print(acc[i])
    
    print(len(acc))