检查两个 int 数组是否有重复元素,并从中提取重复元素之一
Checking if two int arrays have duplicate elements, and extract one of the duplicate elements from them
我正在尝试编写一个方法 union(),它将 return 一个 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.
使用 Java 的流可以使这变得非常简单:
public int[] union(int[] array1, int[] array2) {
return Stream.of(array1, array2).flatMapToInt(Arrays::stream).distinct().toArray();
}
用Collection
API或Stream
API会容易很多。但是,您已经提到您想纯粹使用数组来完成它而不导入任何 class,这将需要一些冗长(尽管简单)的处理单元。驱动逻辑的最重要的理论是如何(在下面给出)计算并集:
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]
即使存在仅使用数组的所有限制,您也可以大大简化代码。无需检查 sets
。刚刚:
分配一个数组来存储并集的所有元素(即 int[] tmp_union
),最坏情况下是两个数组中的所有元素array1
和 array2
.
迭代array1
的元素并将它们与tmp_union
数组中的元素进行比较,只有当时才将它们添加到tmp_union
数组中]他们还没有被添加到那个数组。
为 array2
.
重复 2)
在此过程中,跟踪到目前为止添加到 tmp_union
数组的元素数量(即 added_so_far
)。最后,将 tmp_union
数组中的元素复制到一个新数组( 即 unionArray
),并为联合元素分配 space .代码看起来像:
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;
}
我正在尝试编写一个方法 union(),它将 return 一个 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.
使用 Java 的流可以使这变得非常简单:
public int[] union(int[] array1, int[] array2) {
return Stream.of(array1, array2).flatMapToInt(Arrays::stream).distinct().toArray();
}
用Collection
API或Stream
API会容易很多。但是,您已经提到您想纯粹使用数组来完成它而不导入任何 class,这将需要一些冗长(尽管简单)的处理单元。驱动逻辑的最重要的理论是如何(在下面给出)计算并集:
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]
即使存在仅使用数组的所有限制,您也可以大大简化代码。无需检查 sets
。刚刚:
分配一个数组来存储并集的所有元素(即
int[] tmp_union
),最坏情况下是两个数组中的所有元素array1
和array2
.迭代
array1
的元素并将它们与tmp_union
数组中的元素进行比较,只有当时才将它们添加到tmp_union
数组中]他们还没有被添加到那个数组。为
重复 2)array2
.
在此过程中,跟踪到目前为止添加到 tmp_union
数组的元素数量(即 added_so_far
)。最后,将 tmp_union
数组中的元素复制到一个新数组( 即 unionArray
),并为联合元素分配 space .代码看起来像:
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;
}