简体   繁体   中英

Finding all possible combinations of a given array in Java

I'm working on a problem in Java to find all possible combinations given an arbitrary starting array, by decrementing the values one at a time of each item in the array until the value 1 is reached at each index.

I've started on the below test case but haven't got very far. I would like some help in solving my problem please.

import org.junit.Assert;
import org.junit.Test;

public class ComboTest
{
    @Test
    public void test()
    {
        int[][] answers = {
            {4, 3, 2}, {3, 3, 2}, {2, 3, 2}, {1, 3, 2}, 
            {4, 2, 2}, {3, 2, 2}, {2, 2, 2}, {1, 2, 2}, 
            {4, 1, 2}, {3, 1, 2}, {2, 1, 2}, {1, 1, 2},

            {4, 3, 1}, {3, 3, 1}, {2, 3, 1}, {1, 3, 1}, 
            {4, 2, 1}, {3, 2, 1}, {2, 2, 1}, {1, 2, 1}, 
            {4, 1, 1}, {3, 1, 1}, {2, 1, 1}, {1, 1, 1},
        };


        int[] start = {4, 3, 2};

        int dim = 1;
        for (int i = 0; i < start.length; i++)
        {
            dim *= start[i];
        }

        int[][] combos = new int[dim][start.length];

        for (int i = 0; i < combos[0].length; i++)
        {
            combos[0][i] = start[i];
        }

        for (int i = 1; i < combos.length; i++)
        {
            for (int j = 0; j < combos[i].length; j++)
            {
                int k = combos[i - 1][j] - 1;

                if (k < 1)
                {
                    k = start[j];
                }

                combos[i][j] = k;
            }
        }

        for (int i = 0; i < combos.length; i++)
        {
            for (int j = 0; j < combos[i].length; j++)
            {
                Assert.assertEquals(answers[i][j], combos[i][j]);
            }
        }
    }
}

you Seaching all permutation of an Array with n elements so this is Already asked here

Permutation algorithm for array of integers in Java

This is not my Answer im Only Refering to it

static ArrayList<int[]> permutations(int[] a) {
    ArrayList<int[]> ret = new ArrayList<int[]>();
    permutation(a, 0, ret);
    return ret;
}

public static void permutation(int[] arr, int pos, ArrayList<int[]> list){
    if(arr.length - pos == 1)
        list.add(arr.clone());
    else
        for(int i = pos; i < arr.length; i++){
            swap(arr, pos, i);
            permutation(arr, pos+1, list);
            swap(arr, pos, i);
        }
}

public static void swap(int[] arr, int pos1, int pos2){
    int h = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = h;
}

This is a simple state search problem. You have a starting state, and you can expand it (create its children) following some criteria. In your case, by decrementing one of the values, but not below some lower bound.

If you're not familiar with DFS or BFS, I suggest reading on those. In the meantime, here's the code (perhaps the solution is not in the format you're expecting, but you can work on it :D):

public class ComboTest {
    public static class Combo {
        private Integer[] values;

        public Combo(Integer[] values) {
            this.values = values;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + Arrays.hashCode(values);
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (!(obj instanceof Combo)) {
                return false;
            }
            Combo other = (Combo) obj;
            if (!Arrays.equals(values, other.values)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return Arrays.toString(values);
        }

    }

    public static Set<Combo> combos(Combo start, int lowerBound) {
        Set<Combo> answers = new HashSet<Combo>();

        compute(start, lowerBound, answers);

        return answers;
    }

    private static void compute(Combo start, int lowerBound, Set<Combo> answers) {
        Deque<Combo> dfsStack = new ArrayDeque<Combo>();

        dfsStack.push(start);

        while (!dfsStack.isEmpty()) {
            Combo current = dfsStack.pop();
            answers.add(current);

            for (Combo next : expand(current, lowerBound)) {
                if (!answers.contains(next)) {
                    dfsStack.push(next);
                }
            }
        }
    }

    private static List<Combo> expand(Combo current, int lowerBound) {
        List<Combo> nexts = new ArrayList<Combo>();

        for (int i = 0; i < current.values.length; i++) {
            if (current.values[i] > lowerBound) {
                Integer[] copyCurrent = Arrays.copyOf(current.values, current.values.length);
                copyCurrent[i]--;
                nexts.add(new Combo(copyCurrent));
            }
        }

        return nexts;
    }

    public static void main(String[] args) {
        Combo start = new Combo(new Integer[] { 4, 3, 2 });
        Set<Combo> combos = combos(start, 1);

        for (Combo combo : combos) {
            System.out.println(combo);
        }

        System.out.println(combos.size());
    }

}

Output:

[4, 3, 1]
[2, 1, 1]
[3, 2, 1]
[1, 1, 2]
[2, 2, 2]
[3, 3, 2]
[4, 3, 2]
[4, 2, 1]
[3, 1, 1]
[2, 1, 2]
[3, 2, 2]
[4, 1, 1]
[4, 2, 2]
[3, 1, 2]
[4, 1, 2]
[1, 3, 1]
[1, 2, 1]
[2, 3, 1]
[1, 3, 2]
[1, 1, 1]
[2, 2, 1]
[3, 3, 1]
[1, 2, 2]
[2, 3, 2]
24
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class New{
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        System.out.println("ENTER THE ARRAY SIZE");
        int n=in.nextInt();
        System.out.println("ENTER THE ARRAY VALUES");
        int[] a=new int[n];
        String s="";
        for(int i=0;i<n;i++)
        {
            a[i]=in.nextInt();
            s=s+(char)a[i];
        }
        List<String> hs=mac(s);
        System.out.println("THE COMBINATIONS ARE");
        for(String str:hs)
        {
            char[] ch=str.toCharArray();
            for(int i=0;i<ch.length;i++)
            {
                System.out.print((int)ch[i]);
            }
            System.out.println();
        }

    }
    public static List<String> mac(String s)
    {
        List<String> ss=new ArrayList<String>();
        if(s==null)
        {
            return null;
        }
        else if(s.length()==0)
        {
            ss.add("");
        }
        else
        {
            String str=s.substring(1);
            char c=s.charAt(0);
            List<String> hs=mac(str);
            for(String st:hs)
            {
                for(int i=0;i<=st.length();i++)
                {
                    ss.add(sru(st,c,i));
                }
            }
        }
        return ss;
    }
    public static String sru(String s,char c,int i)
    {
        String start=s.substring(0,i);
        String end=s.substring(i);
        return start+c+end;
    }
}

Easier method: There's a library called Google Guava, that will do this thing for you. You can find it here: https://github.com/google/guava

Idk if this code fits for you but anyway here's the code. Hope it helps :) ...

Collection<List<String>> permutations = null;
String[] foo = //your array in here
permutations = Collections2.permutations(Lists.newArrayList(foo));
//use for each loop to read
for (List<String> permutation : permutations) {
                //Output here
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM