创建一个int数组的int数组,其中包含加起来给定数字的所有可能总和

时间:2011-11-25 09:50:02

标签: java algorithm math multidimensional-array partition-problem

我是Java的全新人物。我正在编写一个Android游戏,我需要生成一个int数组数组,其中包含所有可能的总和(不包括数字2或大于8个数字的组合),它们加起来给定的数字。

例如:  ganeratePatterns(5)必须返回数组

 [patternNumber][summandNumber] = value

 [0][0] = 5

 [1][0] = 1
 [1][1] = 1
 [1][2] = 1
 [1][3] = 1
 [1][4] = 1

 [2][0] = 3
 [2][1] = 1
 [2][2] = 1

 [3][0] = 4
 [3][1] = 1

我已经尝试像Getting all possible sums that add up to a given number那样做了   但是我很难像这样http://introcs.cs.princeton.edu/java/23recursion/Partition.java.html

解决方案

int n = 10; 
int dimension = 0; 
//First we need to count number of posible combinations to create a 2dimensionarray
for(List<Integer> sumt : new SumIterator(n)) {
  if(!sumt.contains(2) && sumt.size() < 9) {
    dimension++;
  }
}

int[][] combinationPattern = new int[dimension][];
int foo = 0;
for(List<Integer> sum : new SumIterator(n)) {
  if(!sum.contains(2) && sum.size() < 9) {
      System.out.println(sum);
      combinationPattern[foo] = toIntArray(sum);
      foo++;
  }
}

这不是100%正确,非常漂亮,但对我的游戏来说已经足够了

我从这里使用了SumIterator类SumIterator.class 我必须将此代码for(int j = n-1; j > n/2; j--) {更改为此for(int j = n-1; j >= n/2; j--) {,因为旧版本不会返回所有组合(例如10 [5,5])

我曾经使用过IntArray函数。我在StackOverflow上创建了野兔,但忘记了一个链接,所以这里是源代码:

public static int[] toIntArray(final Collection<Integer> data){
    int[] result;
    // null result for null input
    if(data == null){
        result = null;
    // empty array for empty collection
    } else if(data.isEmpty()){
        result = new int[0];
    } else{
        final Collection<Integer> effective;
        // if data contains null make defensive copy
        // and remove null values
        if(data.contains(null)){
            effective = new ArrayList<Integer>(data);
            while(effective.remove(null)){}
        // otherwise use original collection
        }else{
            effective = data;
        }
        result = new int[effective.size()];
        int offset = 0;
        // store values
        for(final Integer i : effective){
            result[offset++] = i.intValue();
        }
    }
    return result;
}

1 个答案:

答案 0 :(得分:1)

这不是最漂亮的代码,但它修改了您引用的代码,它可以满足您的需求。它也很快。通过远离递归(使用堆栈)并完全避免字符串到整数的转换,可以使其更快。我可能会回来编辑这些更改。在我漂亮的过时笔记本电脑上运行,它会在5秒内打印50(所有204226个)的分区。

partition(N)退出此代码时,partitions将保留N的分区。

  1. 首先,它以空格分隔格式构建一个字符串表示形式的ArrayList(例如:" 1 1 1")。

  2. 然后创建一个二维的整数数组,可以保存所有结果。

  3. 它将ArrayList中的每个String拆分为一个字符串数组,每个字符串只包含一个数字。
  4. 对于每个String,它通过将每个数字解析为数组来创建一个int数组。
  5. 然后将此int数组添加到int的二维数组中。
  6. 如果您有任何疑问,请与我联系!

        import java.util.ArrayList;
        public class Partition
        {
            static ArrayList<String> list = new ArrayList<String>();
            static int[][] partitions;
    
            public static void partition(int n)
            {
                partition(n, n, "");
                partitions = new int[list.size()][0];
                for (int i = 0; i < list.size(); i++)
                {
                    String s = list.get(i);
                    String[] stringAsArray = s.trim().split(" ");
                    int[] intArray = new int[stringAsArray.length];
                    for (int j = 0; j < stringAsArray.length; j++)
                    {
                        intArray[j] = Integer.parseInt(stringAsArray[j]);
                    }
                    partitions[i] = intArray;
                }
            }
    
            public static void partition(int n, int max, String prefix)
            {
                if(prefix.trim().split(" ").length > 8 || (prefix + " ").contains(" 2 "))
                {
                    return;
                }
                if (n == 0)
                {
                    list.add(prefix);
                    return;
                }
    
                for (int i = Math.min(max, n); i >= 1; i--)
                {
                    partition(n - i, i, prefix + " " + i);
                }
            }
    
            public static void main(String[] args)
            {
                int N = 50;
                partition(N);
    
                /**
                 * Demonstrates that the above code works as intended.
                 */
                for (int i = 0; i < partitions.length; i++)
                {
                    int[] currentArray = partitions[i];
                    for (int j = 0; j < currentArray.length; j++)
                    {
                        System.out.print(currentArray[j] + " ");
                    }
                    System.out.println();
                }
            }
        }