在两个arraylists之间交替。

时间:2013-10-09 00:16:31

标签: java arraylist

我无法运行这个东西。我不确定到目前为止我的情况是否正确。我不太确定在哪里给我一个出界的错误。

以下是说明:

编写一个名为interleave的方法,它接受两个整数a1和a2的ArrayLists作为参数,并在交替索引处将a2的元素插入a1。如果列表长度不等,则较长列表的其余元素将保留在a1的末尾。例如,如果a1存储[10,20,30]和a2存储[4,5,6,7,8],则调用interleave(a1,a2);应该改变a1来存储[10,4,20,5,30,6,7,8]。如果a1已存储[10,20,30,40,50]并且a2已存储[6,7,8],则交错调用(a1,a2);会改变a1来存储[10,6,20,7,30,8,40,50]。

private static void interleave(ArrayList<Integer> a1,
        ArrayList<Integer> a2) {

    int i = a1.size();
    int j = a2.size();

    if (i < j) { // a1 is shorter than a2
        for (int k = 0; k < a1.size(); k++) { // before k passes a1 size
            a1.add(k+1, a2.get(k));
        }

        for (int l = a1.size(); l < a2.size(); l++) {
            a1.add(a1.size(), a2.get(l));
        }

    } else if (i > j) { // a1 is longer than a2
        for (int k = 1; k < a2.size(); k++) {
            a1.add(k+1, a2.get(k));
        }

    } else { // they are equal length
        for (int k = 1; k < a2.size(); k++) {
            a1.add(k+1, a2.get(k));
        }
    }
}

4 个答案:

答案 0 :(得分:3)

这应该有效

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    int i = -1;
    for(Integer elem: a2) {
        if(i < a1.size()-1) {
            i += 2;
        } else {
            i += 1;
        }
        a1.add(i, elem);
    }
}

public static void main(String[] args) throws Exception {

    ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
    ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

    interleave(a1, a2);
    System.out.println(a1);
}

编辑:我不得不承认,这段代码实际上是一个非常糟糕的解决方案,因为对于长列表来说它会非常慢。每次将元素添加到a1时,列表的大部分都必须移动一个位置。 所以按照“MadProgrammer”的建议,这是一个更好,更快的方法来做到这一点

private static void interleave(ArrayList<Integer> a1, ArrayList<Integer> a2) {
    ArrayList<Integer> r = new ArrayList<>(a1.size() + a2.size());

    for(int i = 0, j = 0; i < a1.size() || j < a2.size(); i++, j++) {
        if(i < a1.size()) r.add(a1.get(i));
        if(j < a2.size()) r.add(a2.get(j));
    }
    a1.clear();
    a1.addAll(r);
}

答案 1 :(得分:2)

我看到已经有任何已接受的答案,但我认为这是一种情况,使用具有适当索引变量的for循环将比适用于数组的for循环更方便集合。例如,看看随着时间的推移会发生什么。 a2始终相同:[4 5 6 7 8],应插入a1的元素索引为0, 1, 2, 3, 4。现在,第一个元素(4)应该插入位置a1的{​​{1}}。之后,需要在位置1插入下一个元素(5)。然后需要在3位置插入6。通常,5的{​​{1}}元素需要插入i中的a2位置。这将持续到i*2+1大于a1中的元素数量,或者i*2+1中的元素用尽。考虑到这一点,在插入所有早期元素之后,将a1的{​​{1}}元素插入a2的正确索引为i,因为添加在a2只需在列表末尾添加一个元素。

我同意the comment about not giving away homework answers,但由于已经有完整实现的答案,我想将a1Math.min( i*2+1, l1.size() )循环的索引进行对比,我将包括代码在这里。更新的l1.size()方法是

for

但这不一定是最有效的实施方式。当你到达for-each的末尾时,完成interleave循环并简单地一次性添加剩余的元素会更有意义。我也写了这个来取public static <T> List<T> interleave( final List<T> l1, final List<T> l2 ) { for ( int i = 0; i < l2.size(); i++ ) { l1.add( Math.min( i*2+1, l1.size()), l2.get( i )); } return l1; } s,因为这是所有代码所依赖的,尽管使用for的随机访问只会在有效支持它的列表上有效(例如,它会很好对于l1 s,但对链表表现不佳)。这些只是列表的事实也表明您可以使用ListIterators来考虑解决方案。

在上下文中,并使用List方法演示它:

get

在考虑了这个之后,我认为在这里使用ArrayList有一些话要说。它使一些迭代和插入代码更清晰,特别是因为在迭代光标之前插入main 。它也不需要任何复杂的索引算法。这是一个使用import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Interleave { public static <T> List<T> interleave( final List<T> l1, final List<T> l2 ) { for ( int i = 0; i < l2.size(); i++ ) { l1.add( Math.min( i*2+1, l1.size()), l2.get( i )); } return l1; } public static void main(String[] args) { final List<Integer> l1 = new ArrayList<Integer>( Arrays.asList( 10, 20, 30 ) ); final List<Integer> l2 = Arrays.asList( 4, 5, 6, 7 ,8 ); System.out.println( interleave( l1, l2 )); } }

的实现
ListIterator

为避免在每次迭代时检查ListIterator,您可以拆分while循环:

ListIterators

答案 2 :(得分:0)

这对我有用。

private static void interleave(ArrayList<Integer> 
a1, ArrayList<Integer> a2) {
int i = -1;
for(Integer elem: a2) {
    if(i < a1.size()-1) {
        i += 2;
    } else {
        i += 1;
    }
    a1.add(i, elem);
}
}

public static void main(String[] args) throws Exception {

ArrayList<Integer> a1 = new ArrayList<>(Arrays.asList(10, 20, 30));
ArrayList<Integer> a2 = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));

interleave(a1, a2);
System.out.println(a1);
}

答案 3 :(得分:0)

public static LinkedList<Integer> alternate(LinkedList<Integer> list1, LinkedList<Integer> list2){
    List<Integer> newList = new LinkedList<Integer>();
    Iterator<Integer> itr1 = list1.iterator();
    Iterator<Integer> itr2 = list2.iterator();
    while (itr1.hasNext() || itr2.hasNext()){
        if (itr1.hasNext()){
            newList.add(itr1.next());
        }
        if (itr2.hasNext()){
            newList.add(itr2.next());
        }
    }
    return newList;
}