简体   繁体   English

组合算法Java

[英]Combination algorithm Java

I'm trying to write a function: private static ArrayList<boolean[]> Combo(int i, int j) where it'd be a sort of "concrete" implementation of iCj in math:我正在尝试编写 function: private static ArrayList<boolean[]> Combo(int i, int j) ,它是数学中iCj的一种“具体”实现:

Combo(4,2) would return an arraylist of {true, true, false, false}, {true, false, true, false}, {false, true, true, false}, {false, true, false, true}, {false, false, true, true} (in no particular order). Combo(4,2)将返回一个 arraylist {true, true, false, false}, {true, false, true, false}, {false, true, true, false}, {false, true, false, true}, {false, false, true, true} (不分先后)。

Currently, I've got a recursive algorithm like this:目前,我有一个这样的递归算法:

private static ArrayList<boolean[]> Combo(int i, int j) {
        ArrayList<boolean[]> k = new ArrayList<boolean[]>();
        if (i == 1 && j == 0) {
            k.add(new boolean[]{false});
        } else if (i == 1 && j ==1) {
            k.add(new boolean[]{true});
        } else if (j>i) {
            ;
        } else {
            ArrayList<boolean[]> a1 = Combo((byte) i/2,1);
            ArrayList<boolean[]> a2 = Combo((byte) i/2,2);
            ArrayList<boolean[]> a3 = Combo((byte) i/2,3);
            ArrayList<boolean[]> a4 = Combo((byte) i/2,4);
            ArrayList<boolean[]> a5 = Combo((byte) i/2,5);
            ArrayList<boolean[]> a6 = Combo((byte) i/2,6);
            ArrayList<boolean[]> a7 = Combo((byte) i/2,7);
            ArrayList<boolean[]> a8 = Combo((byte) i/2,8);
            ArrayList<boolean[]> a9 = Combo((byte) i/2,9);

            k.addAll(merge(a1,a9,j));
            k.addAll(merge(a2,a8,j));
            k.addAll(merge(a3,a7,j));
            k.addAll(merge(a4,a6,j));
            k.addAll(merge(a5,a5,j));

            
        }
        
        return k;
    }
    
    private static ArrayList<boolean[]> merge(ArrayList<boolean[]> a1, ArrayList<boolean[]> a2, int tot) {
        ArrayList<boolean[]> k = new ArrayList<boolean[]>();
        
        for (boolean[] b : a1) {
            for (boolean[] b1: a2) {
                boolean[] c = new boolean[tot];
                for (int i = 0 ; i< b.length; i++) {
                    c[i] = b[i];
                }
                for (int i = b.length; i<b.length+b1.length; i++) {
                    c[i] = b1[i-b.length];
                }
                k.add(b);
            }
        }
        
        return k;
    }

But I'm getting Exception in thread "main" java.lang.StackOverflowError on line 129.但是我在第 129 行Exception in thread "main" java.lang.StackOverflowError

Can anyone please help me optimize this?谁能帮我优化一下?

Jave method names should always start with a lower case letter. Jave 方法名称应始终以小写字母开头。

You should also use a java.util.List as a method return value.您还应该使用java.util.List作为方法返回值。

I don't like writing recursive code, so I wrote an iterative solution.我不喜欢写递归代码,所以我写了一个迭代解决方案。 I used a bit trick I learned a while back to generate all combinations.我使用了我不久前学到的一些技巧来生成所有组合。 The bit patterns of all the integers from zero to 2^N give all the combinations of N length.从零到 2^N 的所有整数的位模式给出了 N 长度的所有组合。

In this code, I test for the number of true values you're seeking.在这段代码中,我测试了您正在寻找的真实值的数量。

Here are my test results for 4,2 and 6,2.这是我对 4,2 和 6,2 的测试结果。 I formatted the results to fit in the answer.我对结果进行了格式化以适合答案。

[[true, true, false, false], [true, false, true, false], 
 [false, true, true, false], [true, false, false, true], 
 [false, true, false, true], [false, false, true, true]]

[[true, true, false, false, false, false], 
 [true, false, true, false, false, false], 
 [false, true, true, false, false, false], 
 [true, false, false, true, false, false], 
 [false, true, false, true, false, false], 
 [false, false, true, true, false, false], 
 [true, false, false, false, true, false], 
 [false, true, false, false, true, false], 
 [false, false, true, false, true, false], 
 [false, false, false, true, true, false], 
 [true, false, false, false, false, true], 
 [false, true, false, false, false, true], 
 [false, false, true, false, false, true], 
 [false, false, false, true, false, true], 
 [false, false, false, false, true, true]]

Here's the complete runnable code.这是完整的可运行代码。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CombinationAlgorithm {

    public static void main(String[] args) {
        CombinationAlgorithm ca = new CombinationAlgorithm();
        List<boolean[]> comboList = ca.combo(4, 2);
        ca.printList(comboList);
        comboList = ca.combo(6, 2);
        ca.printList(comboList);
    }
    
    public List<boolean[]> combo(int elementCount, int trueCount) {
        List<boolean[]> comboList = new ArrayList<>();
        
        if (elementCount < trueCount) {
            // Return empty list
            return comboList;
        }
        
        int limit = (int) Math.pow(2.0, elementCount);
        for (int index = 0; index < limit; index++) {
            if (Integer.bitCount(index) == trueCount) {
                boolean[] values = new boolean[elementCount];
                for (int bit = 0; bit < elementCount; bit++) {
                    if (getBit(index, bit) == 0) {
                        values[bit] = false;
                    } else {
                        values[bit] = true;
                    }
                }
                comboList.add(values);
            }
        }
        
        return comboList;
    }
    
    private int getBit(int value, int bit) {
        return (value >> bit) & 1;
    }
    
    private void printList(List<boolean[]> comboList) {
        System.out.print("[");
        for (int index = 0; index < comboList.size(); index++) {
            boolean[] values =  comboList.get(index);
            System.out.print(Arrays.toString(values));
            if (index < (comboList.size() - 1)) {
                System.out.print(", ");
            }
        }
        System.out.println("]");
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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