简体   繁体   中英

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. 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.

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). But it doesn't find the special value when there's more than two dices adding up to the number (like 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.

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 concept is that of basic Backtracking

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