Skip to content

Commit 685068d

Browse files
authored
Merge pull request #320 from cicirello/refactor-permutation
Minor code improvements within Permutation and PermutationIterator classes
2 parents e00426d + de9e530 commit 685068d

File tree

3 files changed

+42
-54
lines changed

3 files changed

+42
-54
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased] - 2023-02-26
7+
## [Unreleased] - 2023-03-02
88

99
### Added
1010

1111
### Changed
12-
* Minor optimizations within Permutation class.
12+
* Minor code improvements within Permutation and PermutationIterator classes.
1313

1414
### Deprecated
1515

src/main/java/org/cicirello/permutations/Permutation.java

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.concurrent.ThreadLocalRandom;
2929
import java.util.random.RandomGenerator;
3030
import org.cicirello.math.rand.RandomIndexer;
31+
import org.cicirello.util.ArrayFiller;
3132
import org.cicirello.util.Copyable;
3233

3334
/**
@@ -81,16 +82,11 @@ public Permutation(int n, RandomGenerator r) {
8182
* @param value The integer value of the permutation in the interval: 0..(n!-1).
8283
*/
8384
public Permutation(int n, int value) {
84-
permutation = new int[n];
85-
for (int i = 0; i < n; i++) {
86-
permutation[i] = i;
87-
}
85+
permutation = ArrayFiller.create(n);
8886
for (int i = 0; i < n - 1; i++) {
8987
int j = i + value % (n - i);
9088
int temp = permutation[j];
91-
for (int k = j; k > i; k--) {
92-
permutation[k] = permutation[k - 1];
93-
}
89+
System.arraycopy(permutation, i, permutation, i + 1, j - i);
9490
permutation[i] = temp;
9591
value = value / (n - i);
9692
}
@@ -117,17 +113,12 @@ public Permutation(int n, int value) {
117113
* @param value The integer value of the permutation in the interval: 0..(n!-1).
118114
*/
119115
public Permutation(int n, BigInteger value) {
120-
permutation = new int[n];
121-
for (int i = 0; i < n; i++) {
122-
permutation[i] = i;
123-
}
116+
permutation = ArrayFiller.create(n);
124117
for (int i = 0; i < n - 1; i++) {
125118
BigInteger[] divRem = value.divideAndRemainder(BigInteger.valueOf(n - i));
126119
int j = i + divRem[1].intValue();
127120
int temp = permutation[j];
128-
for (int k = j; k > i; k--) {
129-
permutation[k] = permutation[k - 1];
130-
}
121+
System.arraycopy(permutation, i, permutation, i + 1, j - i);
131122
permutation[i] = temp;
132123
value = divRem[0];
133124
}
@@ -341,18 +332,16 @@ public Permutation copy() {
341332
* @throws UnsupportedOperationException when permutation length is greater than 12.
342333
*/
343334
public int toInteger() {
344-
int N = permutation.length;
345-
if (N > 12)
335+
if (permutation.length > 12)
346336
throw new UnsupportedOperationException(
347337
"Unsupported for permutations of length greater than 12.");
348-
int[] index = new int[N];
349-
for (int i = 0; i < N; i++) index[i] = i;
338+
int[] index = ArrayFiller.create(permutation.length);
350339
int result = 0;
351340
int multiplier = 1;
352-
int factor = N;
353-
for (int i = 0; i < N - 1; i++) {
341+
int factor = permutation.length;
342+
for (int i = 0; i < index.length - 1; i++) {
354343
result += multiplier * index[permutation[i]];
355-
for (int j = permutation[i]; j < N; j++) {
344+
for (int j = permutation[i]; j < index.length; j++) {
356345
index[j]--;
357346
}
358347
multiplier *= factor;
@@ -377,16 +366,14 @@ public int toInteger() {
377366
* @return a mixed radix representation of the permutation
378367
*/
379368
public BigInteger toBigInteger() {
380-
int N = permutation.length;
381-
if (N <= 12) return BigInteger.valueOf(toInteger());
382-
int[] index = new int[N];
383-
for (int i = 0; i < N; i++) index[i] = i;
369+
if (permutation.length <= 12) return BigInteger.valueOf(toInteger());
370+
int[] index = ArrayFiller.create(permutation.length);
384371
BigInteger result = BigInteger.ZERO;
385372
BigInteger multiplier = BigInteger.ONE;
386-
int factor = N;
387-
for (int i = 0; i < N - 1; i++) {
373+
int factor = permutation.length;
374+
for (int i = 0; i < index.length - 1; i++) {
388375
result = result.add(multiplier.multiply(BigInteger.valueOf(index[permutation[i]])));
389-
for (int j = permutation[i]; j < N; j++) {
376+
for (int j = permutation[i]; j < index.length; j++) {
390377
index[j]--;
391378
}
392379
multiplier = multiplier.multiply(BigInteger.valueOf(factor));
@@ -425,8 +412,7 @@ public Permutation getInversePermutation() {
425412
* iff p2.get(j) == i, for all i, j.
426413
*/
427414
public void invert() {
428-
int[] inverse = getInverse();
429-
System.arraycopy(inverse, 0, permutation, 0, inverse.length);
415+
System.arraycopy(getInverse(), 0, permutation, 0, permutation.length);
430416
}
431417

432418
/**
@@ -774,15 +760,11 @@ public void reverse(int i, int j) {
774760
public void removeAndInsert(int i, int j) {
775761
if (i < j) {
776762
int n = permutation[i];
777-
for (int k = i; k < j; k++) {
778-
permutation[k] = permutation[k + 1];
779-
}
763+
System.arraycopy(permutation, i + 1, permutation, i, j - i);
780764
permutation[j] = n;
781765
} else if (i > j) {
782766
int n = permutation[i];
783-
for (int k = i; k > j; k--) {
784-
permutation[k] = permutation[k - 1];
785-
}
767+
System.arraycopy(permutation, j, permutation, j + 1, i - j);
786768
permutation[j] = n;
787769
}
788770
}
@@ -793,13 +775,16 @@ public void removeAndInsert(int i, int j) {
793775
* @param numPositions Number of positions to rotate.
794776
*/
795777
public void rotate(int numPositions) {
796-
if (numPositions >= permutation.length || numPositions < 0)
778+
if (numPositions >= permutation.length || numPositions < 0) {
797779
numPositions = Math.floorMod(numPositions, permutation.length);
798-
if (numPositions == 0) return;
799-
int[] temp = new int[numPositions];
800-
System.arraycopy(permutation, 0, temp, 0, numPositions);
801-
System.arraycopy(permutation, numPositions, permutation, 0, permutation.length - numPositions);
802-
System.arraycopy(temp, 0, permutation, permutation.length - numPositions, numPositions);
780+
}
781+
if (numPositions > 0) {
782+
int[] temp = new int[numPositions];
783+
System.arraycopy(permutation, 0, temp, 0, numPositions);
784+
System.arraycopy(
785+
permutation, numPositions, permutation, 0, permutation.length - numPositions);
786+
System.arraycopy(temp, 0, permutation, permutation.length - numPositions, numPositions);
787+
}
803788
}
804789

805790
/**
@@ -815,7 +800,7 @@ public void rotate(int numPositions) {
815800
* greater than or equal to length().
816801
*/
817802
public void removeAndInsert(int i, int size, int j) {
818-
if ((size == 0) || (i == j)) {
803+
if ((size <= 0) || (i == j)) {
819804
return;
820805
} else if (size == 1) {
821806
removeAndInsert(i, j);
@@ -869,14 +854,15 @@ public Iterator<Permutation> iterator() {
869854
*/
870855
@Override
871856
public String toString() {
872-
String permS = "";
857+
StringBuilder s = new StringBuilder();
873858
if (permutation.length > 0) {
874-
permS += permutation[0];
859+
s.append(permutation[0]);
875860
for (int i = 1; i < permutation.length; i++) {
876-
permS += " " + permutation[i];
861+
s.append(" ");
862+
s.append(permutation[i]);
877863
}
878864
}
879-
return permS;
865+
return s.toString();
880866
}
881867

882868
/**
@@ -912,11 +898,13 @@ public int hashCode() {
912898
private boolean validate(int[] p) {
913899
boolean[] inP = new boolean[p.length];
914900
for (int e : p) {
915-
if (e < 0 || e >= p.length)
901+
if (e < 0 || e >= p.length) {
916902
throw new IllegalArgumentException(
917903
"Elements of a Permutation must be in interval [0, length())");
918-
if (inP[e])
904+
}
905+
if (inP[e]) {
919906
throw new IllegalArgumentException("Duplicate elements are not allowed in a Permutation.");
907+
}
920908
inP[e] = true;
921909
}
922910
return true;

src/main/java/org/cicirello/permutations/PermutationIterator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* JavaPermutationTools: A Java library for computation on permutations and sequences
3-
* Copyright 2005-2022 Vincent A. Cicirello, <https://www.cicirello.org/>.
3+
* Copyright 2005-2023 Vincent A. Cicirello, <https://www.cicirello.org/>.
44
*
55
* This file is part of JavaPermutationTools (https://jpt.cicirello.org/).
66
*
@@ -24,6 +24,7 @@
2424

2525
import java.util.Iterator;
2626
import java.util.NoSuchElementException;
27+
import org.cicirello.util.ArrayFiller;
2728

2829
/**
2930
* Iterator over all permutations of a specified length, n, of the integers in the interval [0,n).
@@ -63,8 +64,7 @@ public PermutationIterator(int n) {
6364
*/
6465
public PermutationIterator(Permutation p) {
6566
this.p = new Permutation(p);
66-
lastSwap = new int[p.length()];
67-
for (int i = 0; i < lastSwap.length; i++) lastSwap[i] = i;
67+
lastSwap = ArrayFiller.create(p.length());
6868
done = false;
6969
}
7070

0 commit comments

Comments
 (0)