如何为多个问题选择所有可能的复选框组合?

时间:2017-07-19 04:39:57

标签: java

如果假设有三个问题并且每个问题都有多个复选框,那么如何为这三个问题选择复选框的所有可能性?

到目前为止,我为每个问题分别得到了所有可能的组合。

对于第一个问题,有三个答案。可能性是:

[A1]
[A2]
[A3]
[A1, A2]
[A1, A3]
[A2, A3]
[A1, A2, A3]

对于第二个问题,有两个答案。可能性是:

[B1]
[B2]
[B1, B2]

到目前为止,我得到了这两个清单。我可以使用嵌套的for循环遍历列表的每个元素来循环遍历每个问题:

for (int i = 0; i < questionAList.size(); i++) {
    for (int j = 0; j < questionBList.size(); j++) {
        // select questionA answer
        // for each questionA answer select question B answer
    }
}

这样我可以为多个问题选择所有可能的答案。

但是这个嵌套的for循环只有在只有两个问题的情况下才有效。如何通过更通用的方法解决这个问题?

这是我到目前为止所得到的:

{
  "Q: Headache:" : {
    "1" : "[wakes you up at night]",
    "2" : "[about the same time of day]",
    "3" : "[None of the above]",
    "4" : "[wakes you up at night, about the same time of day]"
  },
    "Q: Confusion" : {
    "1" : "[better with drinking fluids]",
    "2" : "[better with rest]",
    "3" : "[None of the above]",
    "4" : "[better with drinking fluids, better with rest]"
  },
   "Q: Confusion associated with …" : {
    "1" : "[HIV illness]",
    "2" : "[None of the above]"
  }
}

只有答案的组合&#34;以上都不是&#34;。

1 个答案:

答案 0 :(得分:0)

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import com.google.common.collect.Sets;

public class CombinationsTest {

    public static void main(String[] args) {

        Map<Integer, Integer> questionAnswersMap = new LinkedHashMap<>();
        questionAnswersMap.put(1, 2);
        questionAnswersMap.put(2, 3);

        Set<Set<Integer>> combinations = new LinkedHashSet<>();
        List<Set<Set<Integer>>> combinationsList = new LinkedList<>();

        for (Entry<Integer, Integer> entry : questionAnswersMap.entrySet()) {
            combinations = getCombinations(createHashSet(entry.getValue()));
            combinationsList.add(combinations);
        }

        for(Set set: combinationsList){
            System.out.println(set);
        }
        Set<List<Set<Integer>>> totalCombinations = Sets.cartesianProduct(combinationsList);

        List<Set<Integer>> result = new LinkedList<>();
        process(totalCombinations, result);

        for (int i = 1; i <= result.size(); i++) {
            System.out.println("Combination " + i + " of " + result.size() + " : " + result.get(i-1));
        }

    }

    public static void process(Set<List<Set<Integer>>> totalCombinations, List<Set<Integer>> result) {

        for (List<Set<Integer>> combinations : totalCombinations) {
            result.addAll(combinations);
        }
    }

    public static Set<Set<Integer>> getCombinations(Set<Integer> options) {

        Set<Set<Integer>> combinations = new LinkedHashSet<>();

        for (int i = 1; i <= options.size(); i++) {
            Set<Set<Integer>> temp = generateCombinations(options, i);
            combinations.addAll(temp);

            for (Set<Integer> set : temp) {
                if (set.size() > 1 && set.contains(options.size())) {
                    combinations.remove(set);
                }
            }
        }

        return combinations;
    }

    protected static Set<Set<Integer>> generateCombinations(Set<Integer> options, int size) {

        Set<Set<Integer>> elements = Sets.powerSet(options);
        Set<Set<Integer>> possibleCombinations = elements.stream().filter(p -> p.size() == size)
                .collect(Collectors.toSet());

        return possibleCombinations;
    }

    public static Set<Integer> createHashSet(int answersCount) {

        Set<Integer> answers = Sets.newHashSet();
        for (int i = 1; i <= answersCount; i++) {
            answers.add(i);
        }
        return answers;
    }
}

输出:

[[1], [2]]
[[1], [2], [3], [1, 2]] 
Combination 1 of 16 : [1]
Combination 2 of 16 : [1]
Combination 3 of 16 : [1]
Combination 4 of 16 : [2]
Combination 5 of 16 : [1]
Combination 6 of 16 : [3]
Combination 7 of 16 : [1] 
Combination 8 of 16 : [1, 2]
Combination 9 of 16 : [2]
Combination 10 of 16 : [1]
Combination 11 of 16 : [2]
Combination 12 of 16 : [2]
Combination 13 of 16 : [2]
Combination 14 of 16 : [3]
Combination 15 of 16 : [2]
Combination 16 of 16 : [1, 2]