com.fujitsu.vdmj.traces.PermuteArray Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
*
* Copyright (c) 2016 Fujitsu Services Ltd.
*
* Author: Nick Battle
*
* This file is part of VDMJ.
*
* VDMJ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VDMJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VDMJ. If not, see .
* SPDX-License-Identifier: GPL-3.0-or-later
*
******************************************************************************/
// Based on source from http://www.merriampark.com/perm.htm
package com.fujitsu.vdmj.traces;
import java.util.Arrays;
public class PermuteArray
{
private int[] a;
private long numLeft;
private long total;
//-----------------------------------------------------------
// Constructor. WARNING: Don't make n too large.
// Recall that the number of permutations is n!
// which can be very large, even when n is as small as 20 --
// 20! = 2,432,902,008,176,640,000 and
// 21! is too big to fit into a Java long, which is
// why we use BigInteger instead.
//----------------------------------------------------------
public PermuteArray(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 = total;
}
//------------------------------------------------
// Return number of permutations not yet generated
//------------------------------------------------
public long getNumLeft()
{
return numLeft;
}
//------------------------------------
// Return total number of permutations
//------------------------------------
public long getTotal()
{
return total;
}
//-----------------------------
// Are there more permutations?
//-----------------------------
public boolean hasNext()
{
return numLeft > 0;
}
//------------------
// Compute factorial
//------------------
private static long getFactorial(int n)
{
return n == 1 ? 1 : n * getFactorial(n-1);
}
//--------------------------------------------------------
// Generate next permutation (algorithm from Rosen p. 284)
//--------------------------------------------------------
public int[] next()
{
if (numLeft == total)
{
numLeft = numLeft - 1;
return a;
}
int temp;
// Find largest index j with a[j] < a[j+1]
int j = a.length - 2;
while (a[j] > a[j + 1])
{
j--;
}
// Find index k such that a[k] is smallest integer
// greater than a[j] to the right of a[j]
int k = a.length - 1;
while (a[j] > a[k])
{
k--;
}
// Interchange a[j] and a[k]
temp = a[k];
a[k] = a[j];
a[j] = temp;
// Put tail end of permutation after jth position in increasing order
int r = a.length - 1;
int s = j + 1;
while (r > s)
{
temp = a[s];
a[s] = a[r];
a[r] = temp;
r--;
s++;
}
numLeft = numLeft - 1;
return a;
}
public static void main(String[] args)
{
PermuteArray p = new PermuteArray(4);
while (p.hasNext())
{
System.out.println(Arrays.toString(p.next()));
}
}
}