当前位置: 首页 > 知识库问答 >
问题:

检查两个int数组是否有重复元素,并从中提取其中一个重复元素

郑浩博
2023-03-14

我正在尝试编写一个方法union(),它将返回一个int数组,它需要两个int数组参数,并检查它们是否为集合,或者换句话说,它们之间是否存在重复项。我编写了另一个方法isSet(),它接受一个数组参数并检查数组是否为集合。问题是我想检查union方法中的两个数组之间是否有重复项,如果有,我想提取其中一个重复项并将其放入unionArray[]int数组中。这就是我到目前为止所尝试的。

public int[] union(int[] array1, int[] array2){
  
  int count = 0;
  if (isSet(array1) && isSet(array2)){
     for (int i = 0; i < array1.length; i++){
        for (int j = 0; j < array2.length; j++){
           if (array1[i] == array2[j]){ 
              System.out.println(array2[j]);
              count ++;
           }
        }
     }
  }
  int[] array3 = new int[array2.length - count];
     
  int[] unionArray = new int[array1.length + array3.length];
  int elementOfUnion = 0;
      
  for (int i = 0; i< array1.length; i++){
     unionArray[i] = array1[i];
     elementOfUnion = i + 1 ;
  }
  int index = 0;
  for (int i = elementOfUnion; i < unionArray.length; i++){
     unionArray[i] = array3[index];
     index++;
  }
  
  
  return unionArray;
}


public boolean isSet(int[] array){
  boolean duplicates = true;
  
  for (int i = 0; i < array.length; i++){
     for(int n = i+1; n < array.length; n++){
        if (array[i] == array[n])
           duplicates = false;
     }
  }
     
  return duplicates;
}

我想做的是使用unionArray中的所有array1元素,检查array2是否与array1有任何重复,然后将所有非重复元素从array2移动到新的array3,并将array3连接到unionArray。

共有3个答案

越季萌
2023-03-14

即使有仅使用数组的所有限制,也可以大大简化代码。无需检查集合。只是:

>

  • 分配一个数组来存储联合体的所有元素(即,int[]tmp_union),最坏情况下,它将是来自两个数组array1array2的所有元素。

    遍历array1的元素,并将它们与tmp_union数组中的元素进行比较,仅当它们尚未添加到tmp_union数组中时才将它们添加到该数组中。

    array2重复2)。

    在此过程中,跟踪到目前为止添加到tmp_union数组中的元素数量(即added_so_far)。最后,将tmp_union数组中的元素复制到一个新数组(即unionArray)中,并为联合元素分配空间。代码如下所示:

    public static int[] union(int[] array1, int[] array2){
        int[] tmp_union = new int[array1.length + array2.length];
        int added_so_far = add_unique(array1, tmp_union, 0);
            added_so_far = add_unique(array2, tmp_union, added_so_far);
        return copyArray(tmp_union, added_so_far);
    }
    
    private static int[] copyArray(int[] ori, int size) {
        int[] dest = new int[size];
        for(int i = 0; i < size; i++)
            dest[i] = ori[i];
        return dest;
    }
    
    private static int add_unique(int[] array, int[] union, int added_so_far) {
        for (int element : array)
            if (!is_present(union, added_so_far, element))
                union[added_so_far++] = element;
        return added_so_far;
    }
    
    private static boolean is_present(int[] union, int added_so_far, int element) {
        for (int z = 0; z < added_so_far; z++)
             if (element == union[z])
                 return true;
        return false;
    }
    

  • 吴胜涝
    2023-03-14

    使用Java的流可以让这变得非常简单:

    public int[] union(int[] array1, int[] array2) {
        return Stream.of(array1, array2).flatMapToInt(Arrays::stream).distinct().toArray();
    }
    
    史智志
    2023-03-14

    使用CollectionAPI或StreamAPI将更加容易。但是,您已经提到,您希望纯粹使用数组来完成这项工作,而不导入任何类,这将需要几个冗长(尽管很简单)的处理单元。推动这一逻辑的最重要理论是如何(如下所示)计算工会:

    n(A U B) = n(A) + n(B) - n(A ∩ B)
    

    n(Only A) = n(A) - n(A ∩ B)
    n(Only B) = n(B) - n(A ∩ B)
    

    下图描述了该解决方案的高级摘要:

    其余的逻辑已经通过代码本身的注释非常清楚地提到了。

    public class Main {
        public static void main(String[] args) {
            // Test
            display(union(new int[] { 1, 2, 3, 4 }, new int[] { 3, 4, 5, 6 }));
            display(union(new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }));
            display(union(new int[] { 1, 2, 3, 4 }, new int[] { 1, 2, 3, 4 }));
            display(union(new int[] { 1, 2, 3, 4 }, new int[] { 3, 4 }));
            display(union(new int[] { 1, 2, 3, 4 }, new int[] { 4, 5 }));
            display(union(new int[] { 1, 2, 3, 4, 5, 6 }, new int[] { 7, 8 }));
        }
    
        public static int[] union(int[] array1, int[] array2) {
            // Create an array of the length equal to that of the smaller of the two array
            // parameters
            int[] intersection = new int[array1.length <= array2.length ? array1.length : array2.length];
            int count = 0;
    
            // Put the duplicate elements into intersection[]
            for (int i = 0; i < array1.length; i++) {
                for (int j = 0; j < array2.length; j++) {
                    if (array1[i] == array2[j]) {
                        intersection[count++] = array1[i];
                    }
                }
            }
    
            // Create int []union of the length as per the n(A U B) = n(A) + n(B) - n(A ∩ B)
            int[] union = new int[array1.length + array2.length - count];
    
            // Copy array1[] minus intersection[] into union[]
            int lastIndex = copySourceOnly(array1, intersection, union, count, 0);
    
            // Copy array2[] minus intersection[] into union[]
            lastIndex = copySourceOnly(array2, intersection, union, count, lastIndex);
    
            // Copy intersection[] into union[]
            for (int i = 0; i < count; i++) {
                union[lastIndex + i] = intersection[i];
            }
    
            return union;
        }
    
        static int copySourceOnly(int[] source, int[] exclude, int[] target, int count, int startWith) {
            int j, lastIndex = startWith;
            for (int i = 0; i < source.length; i++) {
                // Check if source[i] is present in intersection[]
                for (j = 0; j < count; j++) {
                    if (source[i] == exclude[j]) {
                        break;
                    }
                }
    
                // If j has reached count, it means `break;` was not executed i.e. source[i] is
                // not present in intersection[]
                if (j == count) {
                    target[lastIndex++] = source[i];
    
                }
            }
            return lastIndex;
        }
    
        static void display(int arr[]) {
            System.out.print("[");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(i < arr.length - 1 ? arr[i] + ", " : arr[i]);
            }
            System.out.println("]");
        }
    }
    

    输出:

    [1, 2, 5, 6, 3, 4]
    [1, 2, 3, 4, 5, 6]
    [1, 2, 3, 4]
    [1, 2, 3, 4]
    [1, 2, 3, 5, 4]
    [1, 2, 3, 4, 5, 6, 7, 8]
    
     类似资料:
    • 问题内容: 我有两个div元素。他们每个人都有450px的宽度和高度。如何检查第一个div是否与第二个div重叠? 我尝试使用javascript hittest,但是有点复杂。由于我试图找出其实际工作方式,因此我想从一个简单的代码开始。 我发现可以使用 .getClientRects 来获取元素的边界,但是我不确定如何比较边界。 请给我提意见! 问题答案: 类似这样的东西,并通过getBound

    • 问题内容: 我现在用来检查此功能的函数如下: 有用。我正在寻找的是是否有更好的方法来做到这一点。 问题答案: ECMAScript 2016 包含一种专门用于解决问题的数组方法,因此现在是首选方法。 _从2018年7月开始,如果您需要支持IE,则可以在polyfill中使用几乎所有 主流 浏览器。 编辑:请注意,如果数组中的项目是一个对象,则返回false。这是因为相似的对象是JavaScript

    • 问题内容: 如果该元素是通过方法创建的,如何检查该元素是否存在? 对我不起作用。 问题答案: 对我不起作用。 您需要在元素ID之前添加: 使用香草JavaScript,不需要例如hash(),但是使用jQuery时,确实需要像基于CSS一样将哈希放入目标元素。

    • 我有以下工会: 假设我初始化此并集的实例,如下所示: 如果我理解正确,尝试读取是未定义的行为,因为已设置的和的元素与其重叠。但是,读取也是未定义的行为吗? 编辑:如果C和C在这个问题上的语义学不同,关于C和C的答案非常感谢。

    • 假设我有两个数组,和,其中是的子集: 我想返回如下数组: 如果只是一个数字,那就足够简单了(),但我尝试了y中的等效

    • 我有一个从列表转换的数组,当我试图得到它的形状时,我只得到一个数字。这样地: 而我得到了 然后我试着 我明白了 好像a1的工作原理和a2一样。我能那样想吗?如果我把a1当成a2,除了形状法,会不会有问题?