简体   繁体   English

如何将两个数组列表按升序合并为一个

[英]How to merge two arraylists into one in ascending order

I need to merge two lists into one, in ascending order, not duplicates, and I think my code is really close, I'm just missing something and I can't figure it out. 我需要将两个列表按升序合并为一个列表,而不是重复列表,而且我认为我的代码确实很接近,我只是缺少了一些东西而无法弄清楚。 As of now, my code is not working properly in my merge method. 到目前为止,我的代码在我的merge方法中无法正常工作。 I think it has something to do with my loops, but I just can't work around it. 我认为这与我的循环有关,但我无法解决它。 My current method prints the new list, but it is not in perfect increasing order. 我当前的方法可以打印新列表,但是顺序不是很完美。 I would appreciate any assistance in figuring out how to make this method print my merged list with ascending order using the contents of l1 and l2. 如果能弄清楚如何使此方法使用l1和l2的内容以升序打印合并列表,我将不胜感激。

**Note: I cannot use any built-in array sorting methods. **注意:我不能使用任何内置的数组排序方法。

Thanks! 谢谢!

import java.util.ArrayList;
import java.util.Random;

public class MergeLists {

    public static ArrayList<Integer> merge(ArrayList<Integer> l1, ArrayList<Integer> l2){        
    ArrayList<Integer> mergedList = new ArrayList();
    for (int j = 0; j < l1.size(); j++) {
        if (l1.get(j) < l2.get(j)) {
            mergedList.add(l1.get(j));
            mergedList.add(l2.get(j));
        } else {
            mergedList.add(l2.get(j));
            mergedList.add(l1.get(j));
        }
    }
    for (int i = l2.size() - l1.size(); i < l2.size(); i++) {
        mergedList.add(l2.get(i));
    }
    return mergedList;
}

public static ArrayList<Integer> makeRandomIncreasingList(int length) {
    ArrayList<Integer> randomList = new ArrayList();
    Random rand = new Random();
    int inList = rand.nextInt(9) + 1;
    int inList2 = rand.nextInt(9) + 1;
    for (int i = 0; i < length; i++) {
        randomList.add(inList);
        inList = inList + inList2;
    }
    return randomList;
}

public static void doMergeTest() {
    ArrayList<Integer> list1 = makeRandomIncreasingList(10);
    ArrayList<Integer> list2 = makeRandomIncreasingList(20);
    ArrayList<Integer> mergedList = merge(list1, list2);
    System.out.println("List 1:" + list1);
    System.out.println("List 2:" + list2);
    System.out.println("Merged list:" + mergedList);
}

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        System.out.println("Performing merge test #" + (i + 1) + ":");
        doMergeTest();
    }
}
}

Remove duplicates 删除重复项

arrayList1.remove(arrayList2);

Then merge two arrayList: 然后合并两个arrayList:

arrayList1.addAll(arrayList2);

And Lastly sort the last 最后排序最后

collections.sort(arrayList1);

Another way is to use SET: Set doesnt allow duplicates 另一种方法是使用SET:Set不允许重复
(HashSet is faster depending on the List implementation class) (HashSet更快,具体取决于List实现类)

Set setmerge = new HashSet(list1);

setmerge.addAll(list2);

list1.clear();

list1.addAll(setmerge);

You have assumed l2 items are always bigger than l1 items, since you are adding remainder of l2 items in the end of the list. 您假设l2个项目始终大于l1个项目,因为您要在列表末尾添加l2个项目的其余部分。 You need to compare them with mergedList items and add them accordingly. 您需要将它们与mergedList项目进行比较,并相应地添加它们。

The first part of your merge() method seems ok, if you modify it a little bit. 如果稍微修改一下,merge()方法的第一部分似乎还可以。 You need to be going through both lists in parallel, something like 您需要同时浏览两个列表,例如

int i = 0, j = 0;
for (; i < l1.size() && j < l2.size();)

And compare individual items and increment indices independently, as in 并分别比较各个项目和增量指标,如

if (l1.get(i) < l2.get(j)) {
    ...
    i++;
} else
    ...
    j++;
}

The way you were doing it you were literally going in parallel, which is not always correct (think of lists [1 2 2] and [1 1 1] => your merge would look like [1 1 1 2 1 2]) 您这样做的方式实际上是并行的,这并不总是正确的(考虑列表[1 2 2]和[1 1 1] =>您的合并看起来像[1 1 1 2 1 2])

Then, after your "parallel" for-loop (the one where you're iterating through both lists), one of your indices is always going to break your loop because it's at the end of its list. 然后,在“并行” for循环(您要遍历两个列表的循环)之后,索引之一始终会中断循环,因为它位于列表的末尾。 For in-order merging, I usually declare i, j outside the loop (you'll need then after your first for-loop, like above) and then do something like (in your notation): 对于有序合并,我通常在循环外声明i,j(您需要在您的第一个for循环之后再进行上述操作),然后再执行类似操作(以您的表示法):

for (int i1 = i; i1 < l1.size(); i1++) {
    mergeList.add(l1.get(i1));
}

for (int i2 = j; i2 < l2.size(); i2++) {
    mergeList.add(l2.get(i2));
}

After your first for-loop, you get to the end of exactly one of the lists (someone's going to break the loop), so exactly one of the above loops is going to get executed, and that will contain the remaining items, in order. 你的第一个for循环之后,你得到的名单(谁家要打破循环)的只有一个结束,所以上述环是会得到执行的只有一个 ,那将包含其余的项目,为了。

Edit: your last for-loop of the merge() method is not correct for your purpose. 编辑:您的merge()方法的最后一个for循环不符合您的目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM