如何将x个整数分成y个数组?

时间:2015-04-04 00:19:54

标签: java

情景:

我有X个元素。我需要尽可能均匀地分割/分割这些元素,正好是Y次(不多)。应将任何余数添加到最后一个索引。

问题:执行此操作的最佳方式是什么

代码示例我尝试过

public static void main (String[] args){

    Integer[] payload1 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
    Integer[] payload2 = {0,1,2,3,4,5,6,7,8,9,10,11,12};
    Integer[] payload3 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    Integer[] payload4 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
    Integer[] payload5 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};

    ArrayList<Integer[]> payloads = new ArrayList<Integer[]>();
    payloads.add(payload1);
    payloads.add(payload2);
    payloads.add(payload3);
    payloads.add(payload4);
    payloads.add(payload5);

    int splits = 5;

    for(Integer[] x : payloads){

        int counter = 1;
        for(ArrayList<Integer> i : Segmenter.splitter(x, splits))
            System.out.println(counter+++" "+i.toString()+" Size : "+i.size());

        System.out.println("");
    }
   }

    public static ArrayList<ArrayList<Integer>> splitter(Intger[] payload, int splits){

        int distibution = (payload.length + splits - 1) / splits;
        System.out.println("Distibution : "+distibution);

        ArrayList<ArrayList<Integer>> assembledArray = new ArrayList<ArrayList<Integer>>();
        int size = (payload.length + splits - 1) / splits;

        for(int i = 0; i < payload.length; i++)
        {
            if(i % size == 0)
                assembledArray.add(new ArrayList<Integer>());
            assembledArray.get(i / size).add(payload[i]);
        }

        return assembledArray;
    }
}

由于abagshaw&amp; amp; selbie

上方的结果

Steps : 5
1 [0, 1, 2, 3, 4]
2 [5, 6, 7, 8, 9]
3 [10, 11, 12, 13, 14]
4 [15, 16, 17, 18, 19]
5 [20, 21, 22, 23, 24]

Steps : 3
1 [0, 1, 2]
2 [3, 4, 5]
3 [6, 7, 8]
4 [9, 10, 11]
5 [12]

问题:请注意,应该有6个结果数组(因此splits = 6)。以上情况仅返回此边缘情况下的5个数组

欲望结果示例

当15个元素(加上第0个索引)需要拆分6次时

1 [0, 1, 2]
2 [3, 4, 5]
3 [6, 7, 8]
4 [9, 10, 11]
5 [12, 13, 14]
6 [15]

当12个元素(加上第0个索引)需要拆分6次时

1 [0, 1]
2 [2, 3]
3 [4, 5]
4 [6, 7]
5 [8, 9]
6 [10, 11, 12]

当11个元素(加上第0个索引)需要拆分6次时

1 [0, 1]
2 [2, 3]
3 [4, 5]
4 [6, 7]
5 [8, 9]
6 [10, 11]

当15个元素(加上第0个索引)需要拆分8次

1 [0, 1]
2 [2, 3]
3 [4, 5]
4 [6, 7]
5 [8, 9]
6 [10, 11]
7 [12, 13]
8 [14, 15]

等等..

解决方案(感谢selbie)

https://ideone.com/Bul3NU

2 个答案:

答案 0 :(得分:3)

这是一个更直接的解决方案,有点清洁:

编辑:拆分器符合规则,其中拆分始终等于输出assembleArray.length,并且所有期望的结果都应该有效。

public static ArrayList<ArrayList<Integer>> splitter(int[] payload, int splits){

    ArrayList<ArrayList<Integer>> assembledArray = new ArrayList<ArrayList<Integer>>();
    int[] sizes = new int[splits];
    int j = 0;
    for(j = 0; j < payload.length; j++)
    {
        if(payload.length - j < splits && j % (splits - 1) == 0)
            break;
        sizes[splits - (j % (splits - 1)) - 2]++;
    }
    sizes[sizes.length - 1] = payload.length - j;

    int currentOn = 0;
    int currentIndex = 0;
    for(int i = 0; i < payload.length; i++)
    {
        if(currentOn == 0)
        {
            assembledArray.add(new ArrayList<Integer>());
            currentOn = sizes[currentIndex];
            currentIndex++;
        }
        assembledArray.get(currentIndex - 1).add(payload[i]);
        currentOn--;
    }

    return assembledArray;
}

答案 1 :(得分:1)

不要使用浮点(双精度)来计算steps的值。替换此行:

int steps = (int) Math.ceil(payloadSize/(double)splits);

有了这个:

steps = payloadSize / splits;

然后你的for循环或多或少是你拥有的。这里有一些轻微的调整:

protected ArrayList<ArrayList<Integer>> splitter(int [] payload, int splits)
{
    ArrayList<Integer> segment = null;

    ArrayList<ArrayList<Integer>> assembledArray = new ArrayList<ArrayList<Integer>>();
    int steps = payload.length / splits;


    for(int i=0; i<payload.length; i++) {

        if (segment == null) {
            segment = new ArrayList<Integer>();
            assembledArray.add(segment);
        }

        segment.add(payload[i]);

        if ((segment.size()>=steps) && (assembledArray.size() < splits))
            // null out the segment to indicate a new one must be created
            // unless we are on the last split index
            segment = null;
    }
}
return assembledArray;