开发者

How to mix two arrays in Java?

I have some String[] arrays, for example:

['a1', 'a2']
['b1', 'b2', 'b3', 'b4']
['c1']

How can I mix them, so that I get ['a1', 'b1', 'c1', 'a2', 'b2', 'b3', 'b4'] (0 element of a, then b, c, 1 element of a, b, c and so on)? Thanks

More accurately the resulting array must consist of the first value of the first array, then the first value of the second array, ..., the first value of the last array, the second value of the first array, ..., the second value of the last array, ..., the last value of the biggest array. If arrays are not of the same size, the smaller ones just aren't being taken into account.

Here's an illustration:

a1 a2 a3 a4
b1 b2 b3 b4 b5 b6 b7
c1 c2
d1 d2 d3 d4 d5

Combines into (brackets are just to highlight steps, so they really mean nothing):
(a1 b1 c1 d1) (a2 b2 开发者_高级运维c2 d2) (a3 b3 d3) (a4 b4 d4) (b5 d5) (b6) (b7)

Also, I'd like to combine variable number of array, not just 3 or 4


String result[] = new String[a.length+b.length+c.length];
for (int i = 0, j = 0; j < result.length; ++i) {
    if (i < a.length) {
        result[j++] = a[i];
    }
    if (i < b.length) {
        result[j++] = b[i];
    }
    if (i < c.length) {
        result[j++] = c[i];
    }
}

UPDATE: more generally

String[] merge(String[]... arrays) {
    int length = 0;
    for (String[] a: arrays) {
        length += a.length;
    }
    String result[] = new String[length];
    for (int i = 0, j = 0; j < length; ++i) {
        for (String[] a: arrays) {
            if (i < a.length) {
                result[j++] = a[i];
            }
        }
    }
    return result;
}


String[] answer = new String[a.length + b.length + c.length];
int maxLength = Math.max(a.length, Math.max(b.length, c.length));

int counter = 0;    
for (int i = 0; i < maxLength; i++)
{
   if (i < a.length)
      answer[counter++] = a[i];

   if (i < b.length)
      answer[counter++] = b[i];

   if (i < c.length)
      answer[counter++] = c[i];
}


If I understand you correctly, you need some function which merges your arrays taking 1 next element from each array if the array has next element.

You'll need to create additional array of indexes (see in example) to track when array has or doesn't have elements to merge:

int[] indexes; //should be initialized with 0's 

void int[] mergeArrays(int[] ... arrays) {
   int totalLength = 0;
   for (int[] array : arrays) {
      totalLength += array.length;
   }
   int[] result = new int[totalLength]; 

   indexes = new int[arrays.length];  //array of indexes 
   int mergeIndex = 0;
   while (mergeIndex < totalLength) {
      for (int j = 0; j < arrays.length; j++) {
         if (indexes[j] != -1) {
            changed = true;
            result[mergeIndex++] = arrays[j][indexes[j]];
            indexes[j]++;
            if (arrays[j].length == indexes[j]) {
               indexes[j] = -1;
            } 
         }
      }
   }
   return result;
}


From your description (where you need all the 0th elements, then all the 1st, etc, and where the arrays can be of different sizes), then for an easy-to-understand method (but not the most efficient) I would do the following:

  • create a number of Lists each containing the contents of one of the arrays
  • create a List to hold the end result
  • continually cycle through the Lists, removing the 0th element, and adding it to your result List, until none of the lists contain any more elements

You can avoid creating the lists and do things more efficiently by just having an array of indexes that tell you which element you've got up to in each array, but converting to Lists may make the problem easier to conceptualise.


For a task like that, I would probably roll my own. I would create a new String[] with the size of the a.length + b.length + c.length and then use an old-fashioned for loop, iterating Math.max(a.length, Math.max(b.length, c.length)) times. Inside the loop, I would add an element from each, testing the index against the length before doing so to avoid bounds exceptions.

It has also been correctly pointed out elsewhere that you would need to keep track of the index of the last item added to the aggregate array.


To achieve mixed or combined array from two or more you need one empty array to hold the ones you need to combine or mix. Like this:

    String[] lines1;
    String[] lines2;
    String[] combined = new String [(lines1.length+lines2.length)];

   for (int i = 0, j = 0; j < combined.length; i++) {
       if (i < lines1.length) {
           combined[j] = lines1[i];
           j++;
       }
       if (i < lines2.length) {
           combined[j] = lines2[i];
           j++;
       }
   }

You can shorten the inner condition by assigning to combined[j++] because the incrementing starts afterwards.


ArrayList al = new ArrayList();
al.Add(array1);
al.Add(array2);
al.Add(array3);

that's probably your best bet, or you will run into ArrayIndexOutOfBound-style problems. You'll probably run into this way too


    String[] arr0 = ["a1", "a2"];
    String[] arr1 = ["b1", "b2", "b3", "b4"];
    String[] arr2 = ["c1"];
    int length = arr0.length + arr1.length + arr2.length;
    int max = Math.max(arr0.length, Math.max(arr1.length, arr2.length));
    int index = 0;
    String[] result = new String[length];
    for (int i=0; i<max; i++){
        if (i<arr0.length)
           result[index++] = arr0[i];
        if (i<arr1.length)
           result[index++] = arr1[i];
        if (i<arr2.length)
           result[index++] = arr2[i];
    }


All the answers above are terrible and can be achieved in 3 statements if one reuses System.arraycopy to build an array big enough to hold all the elements from both arrays. After that use the Array.sort methods to sort this big array passing in a Comparator. There is no need to write your own bubble/merge sort when a perfectly fine one already exists.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜