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;
}
3
  • The same as above. And do look into List.iterator() Commented Apr 23, 2013 at 9: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? Commented Apr 23, 2013 at 9: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 :) Commented Apr 23, 2013 at 9:54

10 Answers 10

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

Sign up to request clarification or add additional context in comments.

3 Comments

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?
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.
@mause: I wouldn't consider other means "more basic or intuitive", but for the record, I've added an "access-by-index" solution
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;
}

3 Comments

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<Object>, which is not true. On the other hand, the cast is not necessary...
@LukasEder I assumed, method signature is given so I couldn't change it. However I can see your point.
@Sam: Yes, but then, the cast is dangerous (and unnecessary, in fact)
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]

1 Comment

Thank you :). Your answer and that of Sam are about the thing what I was looking for. Thanks a lot :).
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.

Comments

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());
}

1 Comment

this is good solution.. but while(conditon1 && condition2) replaced to while(conditon1 || condition2)
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 ) );
}

Comments

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());
       }
     }

Comments

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]+" ");
}

}

}

Comments

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>";
    }
?>

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.