如何合并2个数组?

时间:2015-01-26 07:10:40

标签: java arrays

我试图以这种方式合并2个数组:

int[] arr1 = { 1, 3, 9, 5 };
int[] arr2 = { 7, 0, 5, 4, 3 };

现在我需要创建一个如下所示的新数组:

int[] merged = { 1, 3, 9, 5, 7, 0, 4 };

因此我需要将所有数字放在新数组中,但如果两个数组中都有数字,那么它不应该重复,每个数字在merged数组中只应该只有一次。

在同一个数组中,数字永远不会是两次或更多次。

这是我建立的程序:

int[] arr1 = { 1, 6, -6, -9, 3, 4, -8, -7 };
int[] arr2 = { 5, 3, 2, 1, 70, 6, 7, -9, 99, 81 };

int counter = arr1.length;

boolean b = true;

for (int i = 0; i < arr1.length; i++) {
    for (int j = 0; j < arr2.length && b == true; j++) {
        if (arr1[i] == arr2[j])
            b = false;
    }

    if (b == true) {
        counter++;
    }

    b = true;
}

System.out.println(counter);

由于某种原因,它不起作用..

我正在尝试编写没有内置函数或列表的程序,谢谢。

8 个答案:

答案 0 :(得分:2)

不使用ListSet或任何第三方库(准备好Java 101家庭作业):

int[] arr1 = { 1, 6, -6, -9, 3, 4, -8, -7 };
int[] arr2 = { 5, 3, 2, 1, 70, 6, 7, -9, 99, 81 };

// Create a boolean array with the same length as the first array.
boolean[] duplicates = new boolean[arr1.length];
// Counter for how many duplicates we found.
int numDuplicates = 0;

// Loop through the first array and get all duplicates.
for (int i = 0; i < arr1.length; i++) {
    boolean duplicate = false;
    for (int j = 0; j < arr2.length; j++) {
        if (arr1[i] == arr2[j]) {
            duplicate = true;
            numDuplicates++;
            break;
        }
    }
    duplicates[i] = duplicate;
}

// The length of the merged array will be the two lengths subtracted by the number of
// duplicates we found.
int[] mergedArray = new int[arr1.length + arr2.length - numDuplicates];
int index = 0;

// loop through the first array. Don't add it to the merged array if it is a duplicate.
for (int i = 0; i < arr1.length; i++) {
    if (!duplicates[i]) {
        mergedArray[index] = arr1[i];
        index++;
    }
}

// loop through the second array and add all items.
for (int i = 0; i < arr2.length; i++) {
    mergedArray[index] = arr2[i];
    index++;
}

// optional. sort array
Arrays.sort(mergedArray);

System.out.println(Arrays.toString(mergedArray));

输出:

[-9, -8, -7, -6, 1, 2, 3, 4, 5, 6, 7, 70, 81, 99]

使用Set

public static int[] mergeArrays(int[] arr1, int[] arr2) {
    Set<Integer> set = new HashSet<Integer>();
    for (int x : arr1) {
        set.add(x);
    }
    for (int x : arr2) {
        set.add(x);
    }
    int[] result = new int[set.size()];
    int index = 0;
    for (Iterator<Integer> it = set.iterator(); it.hasNext();) {
        result[index] = it.next();
        index++;
    }
    return result;
}

使用List

public static int[] mergeArrays(int[] arr1, int[] arr2) {
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0, length = arr1.length; i < length; i++) {
        list.add(arr1[i]);
    }
    for (int i = 0, length = arr2.length; i < length; i++) {
        if (!list.contains(arr2[i])) {
            list.add(arr2[i]);
        }
    }
    int length = list.size();
    int[] result = new int[length];
    for (int i = 0; i < length; i++) {
        result[i] = list.get(i);
    }
    return result;
}

答案 1 :(得分:1)

在没有找到代码中的错误的情况下,我可以看到你有一个嵌套循环,这意味着运行时间将是O(N ^ 2)。

通过对两个数组O(Nlog(N))进行排序,然后像在合并排序中一样在单个迭代中合并它们,可以获得更好的运行时间,从而消除了过程中的重复项。总运行时间为O(Nlog(N))。

答案 2 :(得分:1)

据我所知,你正试图计算独特的物品。只计算相同的项目。然后添加array1 length和array2 length减去相同的项目数。试试这个:

    int [] arr1 = {1,6,-6,-9,3,4,-8,-7};
    int [] arr2 = {5,3,2,1,70,6,7,-9,99,81};

    int counter = 0;       

    for(int i=0; i<arr1.length; i++) {
        for(int j=0; j<arr2.length; j++) {
            Integer a1=arr1[i];
            Integer a2=arr2[j];
            if( (a1.equals(a2)) ){
                counter++;                  
            }
        }        
    }
    int counterLast=arr1.length+arr2.length-counter;

    System.out.println(counterLast);

答案 3 :(得分:1)

由于您不想要重复,我建议您使用HashSet<Integer>

//add elements from both arrays to the set
HashSet<Integer> set = new HashSet<Integer>();
for (int num : arr1)
    set.add(new Integer(num));

for (int num : arr2)
    set.add(new Integer(num));

// set will have one copy of each of elements in either arr1 and arr2
int[] result = new int[set.size()];
Iterator<Integer> set_iter = set.iterator();
for(int i = 0; set_iter.hasNext(); i++){
    result[i] = set_iter.next();
}
return result;

以下是有关HashSet的更多信息:http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html 这里有关于Iterator的更多信息: http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html

答案 4 :(得分:1)

虽然你的算法效率非常低,但我认为你的代码中存在逻辑错误,循环块应该是这样的:

for(int i=0; i<arr2.length; i++) {
    for(int j=0; j<arr1.length; j++) {
        if(arr2[i] == arr1[j]) {
            b = false;
            break;
        }
    }
    if(b == true) {
        counter++;
    }
    b = true;
}

答案 5 :(得分:1)

根据你的代码,这个程序不能很好地工作,因为两个数组的大小不同,你的外部循环取决于小数组的大小

for(int i = 0; i arr1.length; i ++)

因此当程序达到小数组的大小时程序将结束。所以如果需要这个代码运行良好你需要改变外部(取决于大数组的大小)和内部循环依赖于小数组

int [] arr1 = {1,6,-6,-9,3,4,-8,-7};     int [] arr2 = {5,3,2,1,70,6,7,-9,99,81,55,4};

int counter = arr1.length;


boolean b = true;

for(int i=0; i<arr2.length; i++) {
    for(int j=0; j<arr1.length && b==true; j++) {
        if(arr2[i] == arr1[j])
        {
            b = false;
        }
    }

    if(b == true) {
        counter++;
    }

    b = true;
}

System.out.println(counter);
}

}

答案 6 :(得分:1)

不使用集合和库

//Array copy complexity O(arr1.length + arr2.length)
int arr1Len = arr1.length;
int arr2Len = arr2.length;
int[] both = new int[arr1Len+arr2Len];
int[] result = new int[arr1Len+arr2Len];
System.arraycopy(arr1, 0, both, 0, arr1Len);
System.arraycopy(arr2, 0, both, arr1Len, arr2Len);

//Array sort complexity O(n) < x < O(n lg n)
Arrays.sort(both);

//Sorted array duplication removal O(n)
int counterUnique = 0;
result[0] = both[0];
for (int item : both) {
  if(result[counterUnique] != item){
    result[++counterUnique]=item;
  }
}
//optional
int[] rightSizeResult = Arrays.copyOf(result, counterUnique+1);

Demo


使用Sets

哈希集不包含重复项。对于每个值,都会生成散列并用于访问元素 - 对于大多数情况,您可以> 99.99%确定散列是唯一的。 Hashset不维护顺序,要添加它,您可以使用LinkedHashSet

您无需复制1个数组中的项目,只需

即可
Set<Integer> set = new HashSet<Integer>();
set.addAll(Arrays.asList(arr1));
set.addAll(Arrays.asList(arr2));
Integer[] result = set.toArray(new Integer[set.size()]);

Demo


使用Treeset

Treeset是订单维护集合,没有重复项。

Collection<Integer> result = new TreeSet<Integer>(Arrays.asList(arr1));
result.addAll(Arrays.asList(arr2));

Demo


Nota Bene:

  • 我使用类型整数而不是 int ,这是因为java泛型不适用于基本类型。
  • 在生产代码中,您通常将其写为:

使用Google Guava lib

result = Sets.intersection(ImmutableSet.of(arr1), ImmutableSet.of(arr2));

这有几个原因,但最重要的是,您可以减少非atomic操作期间可能发生的潜在问题。在生产代码中,您主要尝试避免原始类型和数组(如果可以)。它们有很强的用例,但这超出了这个问题的范围。

答案 7 :(得分:1)

您可以使用不允许重复元素的SET。我只使用了一个循环。

    int[] arr1 = { 1, 6, -6, -9, 3, 4, -8, -7 };
    int[] arr2 = { 5, 3, 2, 1, 70, 6, 7, -9, 99, 81 };

    int maxLength = arr1.length >= arr2.length ? arr1.length : arr2.length;
    Set<Integer> merge = new HashSet<Integer>();
    for (int i=0; i<maxLength; i++) {
        if (i < arr1.length)
            merge.add(arr1[i]);
        if (i < arr2.length)
            merge.add(arr2[i]);
    }

    System.out.println(merge.toString());