简体   繁体   English

查找数组中的所有组合

[英]Find all combinations in an array

I'm developing a game in Android Studio using Java, and I have some troubles with the method that does the counting of the score. 我正在使用Java在Android Studio中开发游戏,但是对计算分数的方法有一些麻烦。 Basically in the game I have an array of dices that have values from 1 to 6. Among these values I need to find how many times a special value appears. 基本上在游戏中,我有一个骰子数组,其值从1到6。在这些值中,我需要找出一个特殊值出现多少次。

Right now I have a method that makes it work fine for finding all single values (like all dices that have the value 5), and also if two dices add up to the special value (like 2 + 3, or 1 + 4). 现在,我有一种方法可以使其很好地用于查找所有单个值(例如,所有具有值5的骰子),以及是否两个骰子加起来等于特殊值(例如2 + 3或1 + 4)。 But it doesn't find the special value when there's more than two dices adding up to the number (like 1 + 1 + 3) 但是当有两个以上的骰子加起来时,它找不到特殊值(例如1 + 1 + 3)

Example: If I have the dices with values [1, 2, 2, 2, 3, 5] The result should be three "numberOfPairs" (1+2+2, 2+3, 5) and therefore the method should return 15, but for me it only returns 10. 示例:如果我的骰子具有[1、2、2、2、3、5]值,则结果应为三个“ numberOfPairs”(1 + 2 + 2、2 + 3、5),因此该方法应返回15 ,但对我来说只返回10。

I would really appreciate some ideas how to change this method to work better. 我真的很感谢一些想法,建议如何更改此方法以更好地工作。

Here's the method I've been working on now: 这是我现在正在研究的方法:

public static int evaluatePoints(Dice dices[], int sumToReach) {
    int values[] = new int[dices.length];
    int numberOfPairs = 0;
    int left = 0;
    int right = values.length - 1;

    for(int i = 0; i < dices.length; i++){
            values[i] = dices[i].getValue();
            if(values[i] == sumToReach){
                numberOfPairs++;
                values[i] = 0;
            }

    }

    Arrays.sort(values);

    while (values[right] > sumToReach + values[0]) {
        right--;
    }

    while (left < right) {
        if (values[left] + values[right] == sumToReach) {
            numberOfPairs++;
            left++;
            right--;
        }
        else if(values[left] + values[right]  < sumToReach) {
            left++;
        }
        else right--;
    }
    return numberOfPairs*sumToReach;
}

Your question can be paraphrased as "Get all possible number representations as sum of other natural numbers". 您的问题可以解释为“获取所有可能的数字表示形式以及其他自然数的和”。 Here is pretty good solution. 是很好的解决方案。

Explanation of the Algorithm: 算法说明:

Suppose the input array is [1 2 2 2 3 5]

First the program will search for grpSize 6 i.e. 6 elements that sum upto sum of 5
Then the program will search for grpSize 5 i.e. 5 elements that sum upto sum of 5
.
.
.
then the program will search for grpSize 1 i.e. 1 element that sums upto sum of 5

If a set is found then elements will be removed from the resultList

Warning: This approach is recursive, may lead to stack overflow if number of dice increases manyfold

public static boolean func(int grpSize,int sum,int index,List<Integer> resultList,ArrayList<Integer> values) {
  if(grpSize==1) {
       int j;
       for(j = index; j < resultList.size(); j++) {
           if(resultList.get(j) == sum) {
               values.add(resultList.get(j));
               resultList.remove(j);
               return true;
           }
       }
   }

   for(; index < resultList.size(); index++) {
       if(func(grpSize-1, sum-resultList.get(index), index+1, resultList, values)) {
           values.add(resultList.get(index));
           resultList.remove(index);
           return true;
       }
  }
  return false;   
}


public static void main(String[] args) {
    List<Integer> resultList = new ArrayList<>();
    ArrayList<ArrayList<Integer>> values = new ArrayList<>();

    resultList.add(1);
    resultList.add(2);
    resultList.add(2);
    resultList.add(2);
    resultList.add(3);
    resultList.add(5);
    //3 2 2 2 3 5

    int sum = 5;    
    int n = resultList.size();

    for(int i = 0; i < n; i++) {
        int k=i;
        while(true) {
            values.add(new ArrayList<>());
            func(n-i, sum, 0, resultList, values.get(values.size() - 1));
                if(values.get(k).isEmpty()) {
                    break;
                } else {
                    k++;
                }
            }
        }

        values.removeIf(p -> p.isEmpty());

        System.out.println("Number of pairs: "+values.size());

        values.forEach((it) -> {
            System.out.println(it);
        });

        int temp = 0;

        for(int i = 0; i < values.size(); i++) {
            for(int j = 0; j < values.get(i).size(); j++) {
                temp += values.get(i).get(j);
            }
        }
        System.out.println("sum: "+temp);
    }
}

Working of recursive function: 递归函数的工作:

This function requires 此功能需要

  • Group Size to search for 群组大小以进行搜索
  • The sum to search for 搜索总和
  • The starting index which is always zero(could(should) be cleaned up) 起始索引始终为零(可以(应该)清除)
  • The list of each die roll 每个模具卷的列表
  • The list to add found values 添加发现值的列表

This is boolean function which will return true if a particular set if found to add up to THE SUM. 这是布尔函数,如果发现一个特定的集合加起来等于THE SUM,它将返回true。 The concept is that of basic Backtracking 这个概念就是基本的回溯

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

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