import java.math.BigInteger;
public class PermutationGenerator {
private int[] a;
private BigInteger numLeft;
private BigInteger total;
public PermutationGenerator(int n) {
if (n < 1) {
throw new IllegalArgumentException("Min 1");
}
a = new int[n];
total = getFactorial(n);
reset();
}
public void reset() {
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
numLeft = new BigInteger(total.toString());
}
public boolean hasMore() {
return numLeft.compareTo(BigInteger.ZERO) == 1;
}
//得到组合的总数
private static BigInteger getFactorial(int n) {
BigInteger fact = BigInteger.ONE;
for (int i = n; i > 1; i--) {
fact = fact.multiply(new BigInteger(Integer.toString(i)));
}
return fact;
}
public int[] getNext() {
if (numLeft.equals(total)) {
numLeft = numLeft.subtract(BigInteger.ONE);
return a;
}
// Find largest index j with a[j] < a[j+1]
int j = a.length - 2;
while (a[j] > a[j + 1]) {
j--;
}
//a[]从右向左,找index k,使得a[k]>a[j]
int k = a.length - 1;
while (a[j] > a[k]) {
k--;
}
//a[j]a[k]互换
interchange(a, j, k);
//如果j不是倒数第二个index,则将j+1到a结尾的所有元素,对称互换
int r = a.length - 1;
int s = j + 1;
while (r > s) {
interchange(a, r, s);
r--;
s++;
}
numLeft = numLeft.subtract(BigInteger.ONE);
return a;
}
private static int[] interchange(int[] arr, int indexA, int indexB) {
int temp = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] = temp;
return arr;
}
//测试
public static void main(String[] args) {
int[] indices;
String[] elements = new String[]{"a", "b", "c"};
PermutationGenerator x = new PermutationGenerator(elements.length);
StringBuffer permutation;
while (x.hasMore())
{
permutation = new StringBuffer("%");
indices = x.getNext();
for (int i = 0; i < indices.length; i++) {
permutation.append(elements[indices[i]]).append("%");
}
System.out.println(permutation.toString());
}
}
}
OUTPUT:
%a%b%c%
%a%c%b%
%b%a%c%
%b%c%a%
%c%a%b%
%c%b%a%
分享到:
相关推荐
通过分析和理解这段代码,你可以进一步了解如何使用非递归方法生成全排列,以及如何处理动态添加元素的情况。代码可能涉及到循环、条件判断、数组操作等基本编程概念,通过学习和实践,可以提升对全排列算法的理解和...
全排列的非递归实现。 输入1,2,3,4 得到 [1 2 3 4]..........[4 3 2 1]所有24种排列
在提供的文件名称“新建 文本文档.cpp”中,我们可以推测这是一个C++语言的源代码文件,它很可能包含了实现全排列非递归算法的代码。C++是一种强大的面向对象编程语言,非常适合处理这种需要高效计算的问题。 ...
上传之后才发现头文件少了个ctype.h,因为判断非法输入的时候用到了isalpha(),不加这个头文件的话在gcc下会有警告,在VC下可能编译不过! 首先把输入的各个数由小到大进行排序,然后开始 1.找出比右边数字小的第一...
全排列算法的非递归实现利用了序列的特性,通过调整找到下一个排列,而递归实现则利用了分治策略,将问题分解为更小的部分进行解决。两种方法各有优势,非递归实现空间效率较高,但可能涉及到较多的局部状态调整;...
本文将详细介绍全排列算法的递归实现,以帮助读者理解全排列算法的工作原理及其在递归上的应用。 全排列问题可以简单地表述为:给定一个非空的数字集合,要求出这个集合的所有排列。例如,对于集合{1, 2, 3},它的...
在这个场景中,我们将探讨如何使用Java语言,通过回溯法来递归实现全排列的输出。 首先,我们需要理解回溯法的基本概念。回溯法是一种试探性的解决问题的方法,它尝试逐步构建解决方案,并在每一步中检查当前的解...
总的来说,全排列算法的递归实现简洁直观,但可能会产生重复排列,而字典序法则能确保输出的排列是有序的且不会重复。两者各有优缺点,适用于不同的场景。在实际应用中,根据需求选择合适的方法至关重要。
C++实现全排列是算法中的一种常见问题,解决该问题可以使用递归和非递归两种方法。递归方法可以通过不断地选择每个元素来生成全排列,但是这种方法在元素个数很多时很容易造成堆栈溢出,因此需要找到一种非递归的...
### Python非递归全排列实现方法详解 #### 一、引言 在计算机科学与编程领域,全排列问题是一个常见的组合数学问题。全排列是指从给定的n个不同元素中取出m(m≤n)个元素,按照一定的顺序排列起来的方式。递归...
因此,在实际应用中,我们往往会选择非递归的算法,如回溯法或基于栈的迭代方法,来优化性能。 通过这个实验,学生不仅可以掌握全排列的基本概念,还能深化对递归的理解,提高解决问题的能力。此外,对于数据结构的...
全排列的非递归实现。输入1,2,3 得到 [1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]六种组合
为了解决这个问题,可以考虑使用非递归的回溯法或者动态规划等其他方法。 总之,全排列的递归算法是C语言编程中一种重要的算法实现,通过理解递归思想和巧妙地处理数组元素,我们可以有效地解决这类问题。同时,...
非递归实现则通常使用动态规划,避免重复计算: ```python def fibonacci_iterative(n, memo={}): if n return 0 elif n == 1: return 1 else: if n not in memo: memo[n] = fibonacci_iterative(n-1, memo...
这个C代码展示了全排列的递归实现。`perm`函数接受一个数组、当前处理的元素的索引k和数组长度m。当k大于m时,表示已经到达数组末尾,此时打印当前排列并增加计数器n。否则,遍历k到m的所有元素,与基准点交换位置,...
1. **迭代替代递归**:通过迭代而非递归的方法来生成全排列可以显著减少函数调用的开销。 2. **避免重复计算**:在递归过程中记录已生成的排列,以避免重复计算。 3. **并行处理**:利用多线程或多进程技术来并行...
2. **非递归实现**(使用栈或队列): - 创建一个存储当前排列状态的数据结构,如栈或队列。 - 初始化时,将所有数字加入数据结构,并设置一个标志位表示当前处理到哪个数字。 - 使用循环结构,每次取出未处理的...
- **原理**:Heap’s Algorithm 是一种非递归算法,通过一系列交换操作来生成排列。 - **优点**:实现简洁,效率高。 - **缺点**:虽然实现较为简单,但对于理解算法背后的逻辑有一定的难度。 5. **Steinhaus–...