Reputation: 117
I have this function:
public void func1(int d, double delta, double min, double max )
{
if( d == 1 )
{
for( double i=min ; i <= max ; i++ )
System.out.println(i);
}
if(d == 2 )
{
for( double i=min ; i <= max ; i++ )
for( int j = min ; j <= max ; j++ )
System.out.println(i, j);
}
if(d == 3 )
{
for( double i=min ; i <= max ; i++ )
for( int j = min ; j <= max ; j++ )
for( int k=min ; k <= max ; k++ )
System.out.println(i, j, k );
}
}
How to make it dynamic? I.e.,: how to not use the if
statement so that the function can work with any given d
?
Currently, if I want the function to work with d=5, then I have to write five nested for loops and add an if
statement.
Upvotes: 0
Views: 503
Reputation: 93171
Feels like a homework question but I'll bite.
My answer works like an odometer on a car. You have wheels of digits. When each wheel gets to 9, the next one gets bumped up a slot and the current one return to 0. It uses no recursion and maintain the full array of numbers at all time. Instead of println
, you can add the array to a list of array to capture all permutations. (The last time I touched Java was in 2004 so pardon me if this doesn't look "modern")
import java.util.Arrays;
public class Main {
public static void func1(int d, double delta, double min, double max ) {
double[] arr = new double[d];
int i,j;
for (i = 0; i < d; i++) {
arr[i] = min;
}
System.out.println(Arrays.toString(arr));
while (true) {
// increase the first slot
while (arr[0] < max) {
arr[0] += delta;
System.out.println(Arrays.toString(arr));
}
// find the next slot to increase
i = 1;
while (i < d && arr[i] == max) {
i++;
}
// test of all slots contain the max value
Boolean allMax = true;
for (j = 0; j < d; j++) {
if (arr[j] != max) {
allMax = false;
break;
}
}
if (allMax) {
// if it does, quit the outer while loop
break;
} else if (i < d) {
// if not, increase that next slot
arr[i] += delta;
}
// reset all slots before it
for (j = 0; j < i; j++) {
arr[j] = min;
}
System.out.println(Arrays.toString(arr));
}
}
public static void main(String []args) {
func1(3, 1, 1, 3); // gives 3^3 = 27 permutations
}
}
There are a couple assumptions that I've made:
min < max
delta
steps perfectly from min
to max
. For example, delta = 1, min = 1, max = 10
. I haven't tested cases like delta = 2, min = 1, max = 2
.Upvotes: 0
Reputation: 3577
You can use the idea of Recursion to tackle this problem. The key idea is that if you want to have d
loops, you can simply have a single for-loop, and within that for-loop you will have a function that loops d - 1
times:
loop(int d) {
for (i = min : max) {
loop(d - 1)
}
}
You may refer to the following sample code for reference:
public class Main {
public static void main(String[] args) {
func1(3, 1.0, 3.0);
}
private static void func1(int d, double min, double max) {
func1(d, min, max, "");
}
private static void func1(int d, double min, double max, String prefix) {
if (d == 0) {
System.out.println(prefix);
} else {
for (double i = min; i <= max; i++) {
if (d == 1) {
func1(d - 1, min, max, prefix + i);
} else {
func1(d - 1, min, max, prefix + i + ", ");
}
}
}
}
}
I have modified the code in order to return an array of the double values instead of a string:
public class Main {
private static List<double[]> combination = new LinkedList<>();
private static double[] tmpArray;
public static void main(String[] args) {
func1(3, 1.0, 3.0);
for (double[] result : combination) {
for (int i = 0; i < result.length; i++) {
if (i != result.length - 1) {
System.out.print(result[i] + ", ");
} else {
System.out.print(result[i]);
}
}
System.out.println();
}
}
private static void func1(int d, double min, double max) {
tmpArray = new double[d];
func2(d, min, max);
}
private static void func2(int d, double min, double max) {
if (d == 0) {
//System.out.println(prefix);
double[] newArray = new double[tmpArray.length];
System.arraycopy(tmpArray, 0, newArray, 0, tmpArray.length);
combination.add(newArray);
} else {
for (double i = min; i <= max; i++) {
tmpArray[d - 1] = i;
func2(d - 1, min, max);
}
}
}
}
Upvotes: 1