我目前正在为java创建一个Permutation类。我的这个类的一个方法是advance(),计算机将获取数组,然后显示数组的所有排列。
所以,例如,如果我给数组{0,1,2,3,4,5}或数字6,它应该从012345 ..... 543210给我。
这是我到目前为止的代码:
import java.util.*;
public class Permutation extends java.lang.Object {
public static int[] permutation;
public static int[] firstPerm;
public static int[] lastPerm;
public static int length;
public static int count;
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public Permutation(int n) {
length = n;
permutation = new int[length];
for (int i = 0; i < length; i++) {
permutation[i] = i;
}
}
public Permutation(int[] perm) {
length = perm.length;
permutation = new int[length];
boolean[] t = new boolean[length];
for (int i = 0; i < length; i++) {
if (perm[i] < 0 || perm[i] >= length) {
throw new IllegalArgumentException("INVALID ELEMENT");
}
if (t[perm[i]]) {
throw new IllegalArgumentException("DUPLICATE VALUES");
}
t[perm[i]] = true;
permutation[i] = perm[i];
}
}
public void advance() {
}
public int getElement(int i) {
return permutation[i];
}
public boolean isFirstPerm() {
firstPerm = new int[permutation.length];
for (int i = 0; i < permutation.length; i++) {
firstPerm[i] = permutation[i];
}
Arrays.sort(firstPerm);
if (Arrays.equals(firstPerm, permutation)) {
return true;
} else {
return false;
}
}
public boolean isLastPerm() {
lastPerm = new int[firstPerm.length];
for (int i = 0; i < firstPerm.length; i++) {
lastPerm[i] = firstPerm[firstPerm.length - 1 - i];
}
if (Arrays.equals(permutation, lastPerm)) {
return true;
} else {
return false;
}
}
public static Permutation randomPermutation(int n) {
if (n <= 0) {
throw new IllegalArgumentException("INVALID NUMBER");
} else {
length = n;
permutation = new int[length];
for (int i = 0; i < length; i++) {
permutation[i] = i;
}
Collections.shuffle(Arrays.asList(permutation));
return new Permutation(permutation);
}
}
public void reset() {
Arrays.sort(permutation);
}
public boolean isValid(int[] perm) {
boolean[] t = new boolean[length];
for (int i = 0; i < length; i++) {
if (perm[i] < 0 || perm[i] >= length) {
return false;
}
if (t[perm[i]]) {
return false;
}
}
return true;
}
public int[] toArray() {
return permutation;
}
public String toString() {
StringBuffer result = new StringBuffer();
for (int i = 0; i < permutation.length; i++) {
result.append(permutation[i]);
}
String perms = result.toString();
return perms;
}
public static long totalPermutations(int n) {
count = 1;
for (int i = 1; i <= n; i++) {
count = count * i;
}
return count;
}
}
正如你所看到的,advance()方法是我需要做的最后一件事,但我无法弄清楚。任何帮助都将是盛大的。
答案 0 :(得分:1)
您可以采用的方法之一是:
递归的基本情况是当你遍历整个长度以获得0个元素数组时。然后,打印它或将其添加到List
,您可以在最后返回。
public void advance() {
int[] temp = Arrays.copyOf(arr, arr.length);
printAll(0,temp);
}
private void printAll(int index,int[] temp) {
if(index==n) { //base case..the end of array
//print array temp here
}
else {
for(int i=index;i<n;i++) {//change the first element stepwise
swap(temp,index,i);//swap to change
printAll(index+1, temp);//call recursively
swap(temp,index,i);//swap again to backtrack
}
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
答案 1 :(得分:0)
您的代码现在的样子,听起来您希望能够在外部控制排列类,而不是仅支持按顺序打印所有排列的一个操作。
以下是如何计算排列的示例。
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static int factorial(int x) {
int f = 1;
while (x > 1) {
f = f * x;
x--;
}
return f;
}
public static List<Integer> permute(List<Integer> list, int iteration) {
if (list.size() <= 1) return list;
int fact = factorial(list.size() - 1);
int first = iteration / fact;
List<Integer> copy = new ArrayList<Integer>(list);
Integer head = copy.remove(first);
int remainder = iteration % fact;
List<Integer> tail = permute(copy, remainder);
tail.add(0, head);
return tail;
}
public static void main(String[] args) throws IOException {
List<Integer> list = Arrays.asList(4, 5, 6, 7);
for (int i = 0; i < 24; i++) {
System.out.println(permute(list, i));
}
}
}
只是详细说明,代码背后的想法是将整数(迭代)映射到特定的排列(列表的排序)。我们将它视为排列的基本n表示,其中每个数字表示集合中的哪个元素进入所得排列的位置。
例如,如果我们置换(1,2,3,4),那么我们知道有4个!排列,并且“1”将是3中的第一个元素!其中,然后是(2,3,4)的所有排列。其中3个!新集(2,3,4)的排列,“2”将是2中的第一个元素!他们等等。
这就是为什么我们使用/和%来计算哪个元素进入结果排列的每个位置。
答案 2 :(得分:0)
这应该有效,而且它非常紧凑,唯一的缺点是它是递归的:
private static permutation(int x) {
if (x < 1) {
throw new IllegalArgumentException(x);
}
LinkedList<Integer> numbers = new LinkedList<>();
for (int i = 0; i < x; i++) {
numbers.add(i);
}
printPermutations(numbers, new LinkedList<>());
}
private static void printPermutations(
LinkedList<Integer> numbers, LinkedList<Integer> heads) {
int size = numbers.size();
for (int i = 0; i < size; i++) {
int n = numbers.getFirst();
numbers.removeFirst();
heads.add(n);
printPermutations(numbers, heads);
numbers.add(n);
heads.removeLast();
}
if (numbers.isEmpty()) {
String sep = "";
for (int n : heads) {
System.out.print(sep + n);
sep = " ";
}
System.out.println("");
}
}