如何找到两个数组之间的重复整数并将它们复制到一个新数组中?

How can I find duplicate integers between two arrays and copy them into a new array?

首先,我只使用数组(没有散列映射或数组列表)。

我正在尝试创建一个方法 project,它输入两个不同大小的整数数组。

我正在尝试以某种方式比较它们以获得以下输出:将 [1, 3, 5, 3] 投影到 [2, 1, 6, 3, 1, 4, 5, 3] 结果:[1, 3, 1, 5, 3]。 但是,将 [2, 1, 6, 3, 1, 4, 5, 3] 投影到 [1, 3, 5, 3] 会导致:[1, 3, 5, 3].

我认为嵌套的 for 循环可能是错误的,因为它遍历第一个数组的第一个索引一直到第二个数组,然后转到下一个。

我得到一个 ArrayIndexOutOfBoundsException 用于加星标的行(tempArray[i] == arr1[i],我知道它不应该 tempArray[i] 但不确定到底要放什么)。

我不确定如何以生成上述行的方式比较它们,因为它需要“按顺序”。实现此目标的最佳方法是什么?

我尝试了以下代码:

public int[] project(int[] arr1, int[] arr2) {
    int counter = 0;
    for (int i = 0; i < arr1.length; i++) {
        for (int j = 0; j < arr2.length; j++) {
            if (arr1[i] == arr2[j]) {
                counter++;
            }
        }
    }
    
    int[] tempArray = new int[counter];
    for(int i = 0 ; i < arr1.length; i++) {
        for (int j = 0; j < arr2.length; j++) {
            if(arr1[i] == arr2[j]) {
                tempArray[i] = arr1[i]; // UNDERLINED
            }
        }
    }
}

编辑

ArrayIndexOutOfBounds 错误消失了,但现在我的 return 语句是:将 [1, 3, 5] 投影到 [2, 1, 6, 3, 1, 4, 5, 3] 结果:[1, 3, 5, 0, 0],当它需要时是:将 [1, 3, 5] 投影到 [2, 1, 6, 3, 1, 4, 5, 3] 结果:[1, 3, 1, 5, 3].

知道是什么导致了这个问题吗?

我认为您在第一个 for 循环中有错字

稍后更改

arr1[i] == arr2[i]

arr1[i] == arr2[j]

关于投影数组中的重叠问题,您需要保持与 index 不同的值,而不是 arr1 和 [ 使用的 ij =20=]分别

int[] tempArray = new int[counter];
int index = 0;

for(int i=0 ; i < arr1.length; i++) {
    for (int j=0; j < arr2.length; j++) {
        if(arr1[i] == arr2[j]) {
            tempArray[index++] = arr1[i];
        }
    }
}

对于您期望的值,您应该先遍历 arr2

for(int j=0 ; j < arr2.length; j++) {
    for (int i=0; i < arr1.length; i++) {
        if(arr1[i] == arr2[j]) {
            tempArray[index++] = arr1[i];
        }
    }
}

如果array的内容没有硬编码,你不知道传递的顺序,你可以使用length

  int[] ans;
  if(a.length < b.length) {
      ans = project(a, b);
  } else {
      ans = project(b, a);
  }

输出:

[1, 3, 1, 5, 3]

您当前有索引变量 (i, j) 在循环遍历每个输入数组时跟踪它们的索引,但您还需要跟踪结果的写入头大批。在外部 for 循环之前初始化,比如 int k = 0,然后像这样设置值:tempArray[k++] = array1[i];.

如果您可以执行单个数组复制,则可以放弃第一个循环。初始化一个数组,只要第二个输入数组(因为永远不会有比现有元素更多的重复元素)作为 tempArray。然后,如果您希望它完全适合,请将最终数组初始化为精确长度 k 并使用 System#arrayCopy.

这可能会解决您的问题

public int[] project(int[] arr1, int[] arr2) {
    int counter = 0;
    for (int i : arr2) {
        if (Arrays.binarySearch(arr1, i) >= 0) {
            counter++;
        }
    }
    int[] arr4 = new int[counter];
    int index = 0;
    for (int i : arr2) {
        if (Arrays.binarySearch(arr1, i) >= 0) {
            arr4[index++] = i;
        }
    }

    return arr4;
}

嵌套迭代代价高昂,因此我们希望避免这种情况。要做的第一件事是对我们投影的数组进行排序,这样我们就可以对其执行二进制搜索。其次,不要执行嵌套迭代来确定输出数组大小。创建一个与我们要投影到的数组大小相同的数组,因为它不能超过该长度。

public int[] projection(int[] a, int[] b) {
  int[] temp = new int[b.length];
  int nextIndex = 0;
  for (int x : b) {
    if (contains(a, x)) {
      temp[nextIndex++] = x;
    }
  }
  return slice(temp, nextIndex);
}

private boolean contains(int[] array, int value) {
  for (int element : array) {
    if (element == value) {
      return true;
    }
  }
  return false;
}

private int[] slice(int[] src, int size) {
  int[] slice = new int[size];
  for (int index = 0 ; index < size ; ++index) {
    slice[index] = src[index];
  }
  return slice;
}

对于你的第二个问题,我认为,在你的临时数组中,你应该保存 arr2[j] 的值而不是 arr1[i]

此外,您需要一个不同的计数器(最初设置为 0 并在循环中递增)来设置 tempArray[counter] 中的值。

我的意思是:

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