10

Write a method

public static ArrayList merge(ArrayList a, ArrayList b)

that merges two array lists, alternating elements from both array lists. If one array list is shorter than the other, then alternate as long as you can and then append the remaining elemts from the longer array list. For example, if a is

1 4 9 16

and b is

9 7 4 9 11

then merge returns the array list

1 9 4 7 9 4 16 9 11


What I tried doing was writing a for loop with if statements such that a number is added to the merge array list from array list a when i is an even number (i%2==0) and from array list b when i is an odd number. I am however not sure how to deal with the fact that one array list can be longer than the other. Could anyone please help me out?

EDIT: Ok, here is the code (but it is far from correct):

public static ArrayList<Integer> merge(ArrayList<Integer> een, ArrayList<Integer> twee)
{
    ArrayList<Integer> merged = new ArrayList<Integer>();

    for(int i = 0; i<100; i++)
    {           
        if(i%2!=0)
        {
            merged.add(a.get(i));
        }   
        if(i%2 == 0)
        {
            merged.add(b.get(i));
        }               
    }

    System.out.println(merged);
    return merged;
}
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
dreamer
  • 1,192
  • 5
  • 20
  • 42
  • The same as above. And do look into `List.iterator()` – Anders R. Bystrup Apr 23 '13 at 09:41
  • Ok, sorry. I just thought the code is of such low quality that it wasn't worth posting. However, could anyone of you please provide me with a more 'basic'approach than the one with the List iterator? – dreamer Apr 23 '13 at 09:46
  • 2
    Posting your code, even of bad quality, shows the efforts you made trying to solve your problem and thus you're more likely to get an answer and less likely to get downvoted :) – Autar Apr 23 '13 at 09:54

10 Answers10

15

Iterators seem to do the trick most easily

public static <T> ArrayList<T> merge(Collection<T> a, Collection<T> b) {
    Iterator<T> itA = a.iterator();
    Iterator<T> itB = b.iterator();
    ArrayList<T> result = new ArrayList<T>();

    while (itA.hasNext() || itB.hasNext()) {
        if (itA.hasNext()) result.add(itA.next());
        if (itB.hasNext()) result.add(itB.next());
    }

    return result;
}

Without iterators:

public static <T> ArrayList<T> merge(List<T> a, List<T> b) {
    ArrayList<T> result = new ArrayList<T>();
    int size = Math.max(a.size(), b.size());

    for (int i = 0; i < size; i++) {
        if (i < a.size()) result.add(a.get(i));
        if (i < b.size()) result.add(b.get(i));
    }

    return result;
}

Note, I've relaxed the method signature a bit. If you're implementing the merging using iterators, Collection (or even Iterable) will do. Otherwise, List will do. There is no need to require ArrayList as a method argument type

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
  • Thanks, however, I think I am not supposed to make use of 'iterators' since these were never covered in my lectures. I understand that this is probably the most elegant way to solve the problem, but is there also a more basic and intuitive approach? – dreamer Apr 23 '13 at 09:44
  • mause, you should be able to deduce that yourself from this example. This should help you in the right direction, even if you haven't seen iterators before. – Yuri Apr 23 '13 at 09:46
  • 1
    @mause: I wouldn't consider other means "more basic or intuitive", but for the record, I've added an "access-by-index" solution – Lukas Eder Apr 23 '13 at 09:46
5

Without Iterator:

public static ArrayList merge(ArrayList a, ArrayList b) {
    int c1 = 0, c2 = 0;
    ArrayList<Integer> res = new ArrayList<Integer>();

    while(c1 < a.size() || c2 < b.size()) {
        if(c1 < a.size())
            res.add((Integer) a.get(c1++));
        if(c2 < b.size())
            res.add((Integer) b.get(c2++));
    }
    return res;
}
hamid
  • 2,033
  • 4
  • 22
  • 42
  • If you're explicitly casting list contents to `Integer`, I'd promote that information to the method signature. Your method looks like it could merge `ArrayList`, which is not true. On the other hand, the cast is not necessary... – Lukas Eder Apr 23 '13 at 09:54
  • @LukasEder I assumed, method signature is given so I couldn't change it. However I can see your point. – hamid Apr 23 '13 at 09:55
  • @Sam: Yes, but then, the cast is dangerous (and unnecessary, in fact) – Lukas Eder Apr 23 '13 at 09:57
4

Try this:I implemented using Array.

public static void main(String[] args) {
    int[] first = { 1, 4, 9, 16 };
    int[] second = { 9, 7, 4, 9, 11 };
    int[] merge = new int[first.length + second.length];
    int j = 0, k = 0, l = 0;
    int max = Math.max(first.length, second.length);
    for (int i = 0; i < max; i++) {
        if (j < first.length)
            merge[l++] = first[j++];
        if (k < second.length)
            merge[l++] = second[k++];
    }
    System.out.println(Arrays.toString(merge));
}

Output:

[1, 9, 4, 7, 9, 4, 16, 9, 11]
Achintya Jha
  • 12,735
  • 2
  • 27
  • 39
  • Thank you :). Your answer and that of Sam are about the thing what I was looking for. Thanks a lot :). – dreamer Apr 23 '13 at 09:50
2

You don't need to check modulo, or you'll skip every second element from each input list.

public static <E> List<E> merge(List<E> een, List<E> twee) {
    List<E> merged = new ArrayList<E>(een.size() + twee.size());
    List<E> shorter = een.size() <= twee.size() ? een : twee;
    List<E> longer = een.size() > twee.size() ? een : twee;
    for (int i = 0; i < shorter.size(); i++) {
        merged.add(een.get(i));
        merged.add(twee.get(i));
    }
    for (int i = shorter.size(); i < longer.size(); i++) {
        merged.add(longer.get(i));
    }
    return merged;
}

This generic version works for all kind of Lists and generic types.

jlordo
  • 37,490
  • 6
  • 58
  • 83
1

Here is my solution

LinkedList<Integer> list3 = new LinkedList<Integer>();


Iterator<Integer> itA = list.iterator();
Iterator<Integer> itB = list2.iterator();

while(itA.hasNext() && itB.hasNext()){
    list3.add(itA.next());
    list3.add(itB.next());
}
Loki
  • 1,064
  • 2
  • 26
  • 55
1

I had the same situation and below was my solution:

// array list to hold the merged list
ArrayList<Integer> mergedList = new ArrayList<Integer>();

// Get the bigger size
int maxSize = listOne.size() > listTwo.size() ? listOne.size() : listTwo.size();

// Loop thru the list
for( int i = 0; i <= maxSize; i++){
    // We need to check first if index exist then just add it to mergeList
    if( i < listOne.size() ) mergedList.add( listOne.get( i ) );
    // We need to check first if index exist then just add it to mergeList
    if( i < listTwo.size() ) mergedList.add( listTwo.get( i ) );
}
Rowin
  • 479
  • 4
  • 5
0

Try this

Iterator iterator1 = arr1.iterator();
     Iterator iterator2 = arr2.iterator();
     while (iterator1.hasNext() || iterator2.hasNext()) {
       if(iterator1.hasNext()){
         mergerArr.add(iterator1.next());
       }
       if(iterator2.hasNext()){
         mergerArr.add(iterator2.next());
       }
     }
Jaydeep Rajput
  • 3,605
  • 17
  • 35
0

Array1= {1,2,3} Array2= {a,b,c,d,e}

Output= {1, a, 2, b, 3, c, d, e}

public class MergeArray {

public static void main(String args[])
{
char [] arr1= {'1','2','3'};
char [] arr2= {'a','b','c','d','e'};


int l1= arr1.length;
int l2=arr2.length;

int l3=l1+l2;

char [] arr3=new char[l1+l2];

int i=0;
int j=0;
int k=0;
int m=0;
int r=0;

if(l1<l2)
    r=l1;
else
    r=l2;

while(m<r)
{
    arr3[k++]=arr1[i++];
    arr3[k++]=arr2[j++];
    m++;
}

while(k<l3)
{
    if(l1<l2)
        arr3[k++]=arr2[j++];
    else
        arr3[k++]=arr1[i++];
}

for(int n=0;n<l3;n++)
{
    System.out.print(arr3[n]+" ");
}

}

}

0

I have done this in the following way in php:

<?php
    $list1 = array("a","b","c");
    $list2 = array(1,2,3);
    $list3 = array();
    $j=0;
    $k=0;

    for($i=0;$i<6;$i++)
    {
        if($i%2==0)
        {
            $list3[$i]=$list1[$j];
            $j++;
        }

        else
        {
            $list3[$i]=$list2[$k];
            $k++;
        }

        echo $list3[$i]."<br>";
    }
?>
Paul Karam
  • 4,052
  • 8
  • 30
  • 53
0

OK, my suggestion is to use ArrayList:

public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] list1 = in.nextLine().split(",");
        String[] list2 = in.nextLine().split(",");
        ArrayList<String> merged = new ArrayList<>();
        for (int i = 0; i < Math.max(list1.length,list2.length); i++) {
                merged.add(list1[i]);
                merged.add(list2[i]);
        }
        System.out.println(String.join(",", merged));
    }

You can change the code to Integer if you are sure that the input will be only numbers.