refactor: redesign ArrayCombination
(#5181)
* Related to #5164 (Redesign of ArrayCombination) * Checkstyle fix * Clang_format * refactor: cleanup --------- Co-authored-by: Piotr Idzik <65706193+vil02@users.noreply.github.com> Co-authored-by: vil02 <vil02@o2.pl>
This commit is contained in:
parent
06927d3fda
commit
f83bb659ba
@ -1,32 +1,42 @@
|
|||||||
package com.thealgorithms.backtracking;
|
package com.thealgorithms.backtracking;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all permutations of 1...n of length k
|
* Finds all combinations of 0...n-1 of length k
|
||||||
* @author TheClerici (<a href="https://github.com/TheClerici">git-TheClerici</a>)
|
|
||||||
*/
|
*/
|
||||||
public final class ArrayCombination {
|
public final class ArrayCombination {
|
||||||
private ArrayCombination() {
|
private ArrayCombination() {
|
||||||
}
|
}
|
||||||
private static int length;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all combinations of 1..n by creating an array and using backtracking in Combination.java
|
* Finds all combinations of length k of 0..n-1 using backtracking.
|
||||||
* @param n max value of the array.
|
*
|
||||||
* @param k length of combination
|
* @param n Number of the elements.
|
||||||
* @return a list of all combinations of length k. If k == 0, return null.
|
* @param k Length of the combination.
|
||||||
|
* @return A list of all combinations of length k.
|
||||||
*/
|
*/
|
||||||
public static List<TreeSet<Integer>> combination(int n, int k) {
|
public static List<List<Integer>> combination(int n, int k) {
|
||||||
if (n <= 0) {
|
if (n < 0 || k < 0 || k > n) {
|
||||||
return null;
|
throw new IllegalArgumentException("Wrong input.");
|
||||||
}
|
}
|
||||||
length = k;
|
|
||||||
Integer[] arr = new Integer[n];
|
List<List<Integer>> combinations = new ArrayList<>();
|
||||||
for (int i = 1; i <= n; i++) {
|
combine(combinations, new ArrayList<>(), 0, n, k);
|
||||||
arr[i - 1] = i;
|
return combinations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void combine(List<List<Integer>> combinations, List<Integer> current, int start, int n, int k) {
|
||||||
|
if (current.size() == k) { // Base case: combination found
|
||||||
|
combinations.add(new ArrayList<>(current)); // Copy to avoid modification
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = start; i < n; i++) {
|
||||||
|
current.add(i);
|
||||||
|
combine(combinations, current, i + 1, n, k);
|
||||||
|
current.removeLast(); // Backtrack
|
||||||
}
|
}
|
||||||
return Combination.combination(arr, length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,51 +1,36 @@
|
|||||||
package com.thealgorithms.backtracking;
|
package com.thealgorithms.backtracking;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import com.thealgorithms.maths.BinomialCoefficient;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeSet;
|
import java.util.stream.Stream;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
public class ArrayCombinationTest {
|
public class ArrayCombinationTest {
|
||||||
|
@ParameterizedTest
|
||||||
@Test
|
@MethodSource("regularInputs")
|
||||||
void testNBeingZeroOrLess() {
|
void testCombination(int n, int k, List<List<Integer>> expected) {
|
||||||
List<TreeSet<Integer>> zeroResult = ArrayCombination.combination(0, 1);
|
assertEquals(expected.size(), BinomialCoefficient.binomialCoefficient(n, k));
|
||||||
List<TreeSet<Integer>> negativeResult = ArrayCombination.combination(-1, 1);
|
assertEquals(expected, ArrayCombination.combination(n, k));
|
||||||
assertNull(zeroResult);
|
|
||||||
assertNull(negativeResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void testNoLengthElement() {
|
@MethodSource("wrongInputs")
|
||||||
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 0);
|
void testCombinationThrows(int n, int k) {
|
||||||
assertNull(result);
|
assertThrows(IllegalArgumentException.class, () -> ArrayCombination.combination(n, k));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private static Stream<Arguments> regularInputs() {
|
||||||
void testLengthOne() {
|
return Stream.of(Arguments.of(0, 0, List.of(new ArrayList<Integer>())), Arguments.of(1, 0, List.of(new ArrayList<Integer>())), Arguments.of(1, 1, List.of(List.of(0))), Arguments.of(3, 0, List.of(new ArrayList<Integer>())), Arguments.of(3, 1, List.of(List.of(0), List.of(1), List.of(2))),
|
||||||
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 1);
|
Arguments.of(4, 2, List.of(List.of(0, 1), List.of(0, 2), List.of(0, 3), List.of(1, 2), List.of(1, 3), List.of(2, 3))));
|
||||||
assert result != null;
|
|
||||||
assertEquals(1, result.get(0).iterator().next());
|
|
||||||
assertEquals(2, result.get(1).iterator().next());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private static Stream<Arguments> wrongInputs() {
|
||||||
void testLengthTwo() {
|
return Stream.of(Arguments.of(-1, 0), Arguments.of(0, -1), Arguments.of(2, 100));
|
||||||
List<TreeSet<Integer>> result = ArrayCombination.combination(2, 2);
|
|
||||||
assert result != null;
|
|
||||||
Integer[] arr = result.get(0).toArray(new Integer[2]);
|
|
||||||
assertEquals(1, arr[0]);
|
|
||||||
assertEquals(2, arr[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLengthFive() {
|
|
||||||
List<TreeSet<Integer>> result = ArrayCombination.combination(10, 5);
|
|
||||||
assert result != null;
|
|
||||||
Integer[] arr = result.get(0).toArray(new Integer[5]);
|
|
||||||
assertEquals(1, arr[0]);
|
|
||||||
assertEquals(5, arr[4]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user