我已经在这上面阅读了一些其他堆栈溢出线程:
to find the intersection of two multisets in java
How do I get the intersection between two arrays as a new array?
public static int[] intersection (int [] x, int numELementsInX, int [] y, int numElementsInY) {
我试图检查两个数组以及它们的元素数(numElementsInX和numElementsInY),并返回一个包含数组x和y的公共值的新数组。他们的交集。
Example,if x is{1,3,5,7,9}and y is{9,3,9,4} then
intersection(x, 5, y, 4} should return {3, 9} or {9, 3}
我读过我需要使用LCS算法。谁能给我一个如何做到这一点的例子?数组中的数组和值都被初始化并在另一个方法中生成,然后传递到交集。
感谢任何帮助/澄清。
编辑代码
for (int i=0; i<numElementsInX; i++){
for (int j=0; j<numElementsInY; j++){
if (x[j]==x[i]) { //how to push to new array?;
}
else{
}
}
}
答案 0 :(得分:45)
最简单的解决方案是使用集合,只要您不关心结果中的元素将具有不同的顺序,并且将删除重复项。输入数组array1
和array2
是给定Integer[]
数组的int[]
子数组,对应于您要处理的元素数量:
Set<Integer> s1 = new HashSet<Integer>(Arrays.asList(array1));
Set<Integer> s2 = new HashSet<Integer>(Arrays.asList(array2));
s1.retainAll(s2);
Integer[] result = s1.toArray(new Integer[s1.size()]);
以上内容将返回Integer[]
,如果需要,可以轻松复制并将其内容转换为int[]
。
答案 1 :(得分:14)
如果您对java-8没问题,那么我能想到的最简单的解决方案是使用流和过滤器。实施如下:
public static int[] intersection(int[] a, int[] b) {
return Arrays.stream(a)
.distinct()
.filter(x -> Arrays.stream(b).anyMatch(y -> y == x))
.toArray();
}
答案 2 :(得分:2)
如果您不想使用其他数据结构(如Set),那么基本思路是您希望迭代其中一个数组的元素,并为每个值查看它是否出现在另一个数组中。你怎么看它是否出现在另一个阵列中?遍历另一个数组中的元素,并为每个元素查看其值是否等于您要查找的值。我怀疑,如果你在上课时的目标是学习如何编写Java,但是如果你陷入困境,你可能会考虑用代码更新你的问题,那么在这一点上尝试自己解决这个问题将是最好的服务。你已经写好了,这样你就可以得到更详细的反馈和指示。
答案 3 :(得分:2)
试试这个:
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4, 5};
int[] arr2 = new int[]{3, 2, 5, 9, 11};
getIntersection(arr1, arr2);
}
public static Object[] getIntersection(int[] arr1, int[] arr2) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < arr1.length; i++) {
for (int j = 0; j < arr2.length; j++) {
if (arr1[i] == arr2[j]) {
list.add(arr1[i]);
}
}
}
return list.toArray();
}
答案 4 :(得分:1)
在数组查找交集中使用重复元素。
int [] arr1 = {1,2,2,2,2,2,2,3,6,6,6,6,6,6,};
int [] arr2 = {7,5,3,6,6,2,2,3,6,6,6,6,6,6,6,6,};
Arrays.sort(arr1);
Arrays.sort(arr2);
ArrayList result = new ArrayList<>();
int i =0 ;
int j =0;
while(i< arr1.length && j<arr2.length){
if (arr1[i]>arr2[j]){
j++;
}else if (arr1[i]<arr2[j]){
i++;
}else {
result.add(arr1[i]);
i++;
j++;
}
}
System.out.println(result);
答案 5 :(得分:0)
使用哈希映射查找交集包括重复。
输出:1 2 2 15 9 7 12
public static void main(String[] args) {
int[] arr1 = {1, 2, 2, 1, 5, 9, 15, 9, 7, 7, 12};
int[] arr2 = {1, 2, 2, 3, 4, 15, 9, 7, 12, 14};
printIntersect(arr1, arr2);
}
private static void printIntersect(int[] arr1, int[] arr2) {
Map<Integer, Integer> map = new HashMap<>();
//put first array to map
for (int i = 0; i < arr1.length; i++) {
if (!map.containsKey(arr1[i])) {
map.put(arr1[i], 1);
} else {
map.put(arr1[i], map.get(arr1[i]) + 1);
}
}
//check all value in array two
for (int i = 0; i < arr2.length; i++) {
//if exist and value>1 then decrement value
//if value is 1 remove from map
if (map.containsKey(arr2[i])) {
System.out.print(arr2[i] + " ");
if (map.get(arr2[i]) > 1) {
map.put(arr2[i], map.get(arr2[i]) - 1);
} else {
map.remove(arr2[i]);
}
}
}
}
答案 6 :(得分:0)
如果数组已排序
int a1[]=new int[] {1,2,3,5,7,8};
int a2[]=new int [] {1,5,6,7,8,9};
// get the length of both the array
int n1=a1.length;
int n2=a2.length;
//create a new array to store the intersection
int a3[]=new int[n1];
//run the loop and find the intersection
int i=0,j=0,k=0;
while(i<n1&& j<n2) {
if(a1[i]<a2[j]) {
// a1 element at i are smaller than a2 element at j so increment i
i++;
}else if(a1[i]>a2[j]) {
// a2 element at i are smaller than a2 element at j so increment j
j++;
}else {
// intersection element store the value and increment i, j, k to find the next element
a3[k]=a1[i];
i++;
j++;
k++;
}
}
for(int l=0;l<a3.length;l++) {
System.out.println(a3[l]);
}
答案 7 :(得分:0)
if the arrays are not sorted
int a1[]=new int[] {1,2,3,5,7,8};
int a2[]=new int [] {1,5,6,7,8,9};
// sort both the array
Arrays.sort(a1);
Arrays.sort(a2);
// get the length of both the array
int n1=a1.length;
int n2=a2.length;
//create a new array to store the intersection
int a3[]=new int[n1];
//run the loop and find the intersection
int i=0,j=0,k=0;
while(i<n1&& j<n2) {
if(a1[i]<a2[j]) {
// a1 element at i are smaller than a2 element at j so increment i
i++;
}else if(a1[i]>a2[j]) {
// a2 element at i are smaller than a2 element at j so increment j
j++;
}else {
// intersection element store the value and increment i, j, k to find the next element
a3[k]=a1[i];
i++;
j++;
k++;
}
}
for(int l=0;l<a3.length;l++) {
System.out.println(a3[l]);
}
答案 8 :(得分:0)
我使用Core Java方法(用于循环)和Arrays.copyOf来实现这一点。
public class Intersection {
public void intersection3Arrays(int ar1[], int ar2[], int ar3[]) {
Arrays. sort(ar1);
Arrays. sort(ar2);
Arrays. sort(ar3);
int ar1Len = ar1.length;
int ar2Len = ar2.length;
int ar3Len = ar3.length;
int larArray = ar3Len > (ar1Len > ar2Len ? ar1Len : ar2Len) ? ar3Len : ((ar1Len > ar2Len) ? ar1Len : ar2Len);
System.out.println("The largest array is " +larArray);
int[] inputArray1 = Arrays.copyOf(ar1, larArray);
int[] inputArray2 = Arrays.copyOf(ar2, larArray);
int[] inputArray3 = Arrays.copyOf(ar3, larArray);
Integer[] inputArray11 = new Integer[inputArray1.length];
Integer[] inputArray22 = new Integer[inputArray2.length];
Integer[] inputArray33 = new Integer[inputArray3.length];
for (int i = 0; i < inputArray11.length; i++) {
if (inputArray11[i] == null){
inputArray1[i] = 0;
}
}
for (int i = 0; i < inputArray22.length; i++) {
if (inputArray22[i] == null){
inputArray1[i] = 0;
}
}
for (int i = 0; i < inputArray33.length; i++) {
if (inputArray33[i] == null){
inputArray1[i] = 0;
}
}
for (int i = 0; i < inputArray11.length; i++)
for (int j = 0; j < inputArray22.length; j++)
for (int k = 0; k < inputArray33.length; j++)
if (inputArray11[i] == inputArray22[j] && inputArray11[i] == inputArray33[k]) {
System.out.print(inputArray11[i]+" ");
}
}
public static void main(String[] args) {
Intersection3Arrays arrays = new Intersection3Arrays();
int ar1[] = { 1, 2, 5, 10, 20, 40, 80 };
int ar2[] = { 80, 100, 6, 2, 7, 20 };
int ar3[] = {3, 4, 15, 20, 30, 70, 80, 120};
arrays.intersection3Arrays(ar1, ar2, ar3);
}
}
答案 9 :(得分:0)
如果您想在python中实现它,这是找到交集的一种方式。
#find intersection
def find_intersec(list_a, list_b):
return set(list_a).intersection(list_b)
#since lists are kind of like arrays in python we use two lists
list_a = [ 4, 9, 1, 17, 11, 26, 28, 10,28, 26, 66, 91]
list_b = [9, 9, 74, 21, 45, 11, 63,10]
print(find_intersec(list_a, list_b))
答案 10 :(得分:0)
您可以找到两个数组的 intersection :
T[] result = Arrays.stream(a1)
.filter(new HashSet<>(Arrays.asList(a2))::contains)
.toArray(T[]::new);
其中T
应该可以用引用类型代替,例如字符串,整数等。
尽管以上内容似乎为每个元素创建了一个新集合,但事实并非如此。 只能创建一个实例集。
上面的代码等效于:
List<T> list = new ArrayList<>();
HashSet<T> container = new HashSet<>(Arrays.asList(a2));
for (T s : a1) {
if (container.contains(s)) list.add(s);
}
T[] result = list.toArray(new T[0]);
答案 11 :(得分:0)
我希望本示例将简单地一个。传递两个数组,并且您肯定会得到没有重复项的数组的交集。
private static int[] findInterserctorOfTwoArray(int[] array1, int[] array2) {
Map<Integer,Integer> map=new HashMap<>();
for (int element : array1) {
for (int element2 : array2) {
if(element==element2) {
map.put(element, element);
}
}
}
int[] newArray=new int[map.size()];
int con=0;
for(Map.Entry<Integer, Integer> lst:map.entrySet()) {
newArray[con]=lst.getValue();
con++;
}
return newArray;
}
答案 12 :(得分:0)
答案提供了多种解决方案,所以我决定找出最有效的方法。
Óscar López
Bilesh Ganguly
Ruchira Gayan Ranaweera
ikarayel
String
数组,包含 50% 的公共元素。public static void startTest(String name, Runnable test){
long start = System.nanoTime();
test.run();
long end = System.nanoTime();
System.out.println(name + ": " + (end - start) / 1000000. + " ms");
}
随着使用:
startTest("HashMap", () -> intersectHashMap(arr1, arr2));
startTest("HashSet", () -> intersectHashSet(arr1, arr2));
startTest("Foreach", () -> intersectForeach(arr1, arr2));
startTest("Stream ", () -> intersectStream(arr1, arr2));
public static String[] intersectHashSet(String[] arr1, String[] arr2){
HashSet<String> set = new HashSet<>(Arrays.asList(arr1));
set.retainAll(Arrays.asList(arr2));
return set.toArray(new String[0]);
}
溪流
public static String[] intersectStream(String[] arr1, String[] arr2){
return Arrays.stream(arr1)
.distinct()
.filter(x -> Arrays.asList(arr2).contains(x))
.toArray(String[]::new);
}
Foreach
public static String[] intersectForeach(String[] arr1, String[] arr2){
ArrayList<String> result = new ArrayList<>();
for(int i = 0; i < arr1.length; i++){
for(int r = 0; r < arr2.length; r++){
if(arr1[i].equals(arr2[r]))
result.add(arr1[i]);
}
}
return result.toArray(new String[0]);
}
哈希表
public static String[] intersectHashMap(String[] arr1, String[] arr2){
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < arr1.length; i++)
map.put(arr1[i], 1);
ArrayList<String> result = new ArrayList<>();
for(int i = 0; i < arr2.length; i++)
if(map.containsKey(arr2[i]))
result.add(arr2[i]);
return result.toArray(new String[0]);
}
让我们看看如果我们给方法一个 20
元素的数组会发生什么:
HashMap: 0.105 ms
HashSet: 0.2185 ms
Foreach: 0.041 ms
Stream : 7.3629 ms
正如我们所见,Foreach 方法做得最好。但是 Stream 方法几乎慢了 180 倍。
让我们用 500
元素继续测试:
HashMap: 0.7147 ms
HashSet: 4.882 ms
Foreach: 7.8314 ms
Stream : 10.6681 ms
在这种情况下,结果发生了巨大变化。现在最有效的是HashMap方法。
使用 10 000
元素进行下一个测试:
HashMap: 4.875 ms
HashSet: 316.2864 ms
Foreach: 505.6547 ms
Stream : 292.6572 ms
最快的仍然是HashMap方法。而 Foreach 方法变得相当缓慢。
如果元素少于 50 个,那么最好使用 Foreach
方法。他在这一类的速度上强势突破。
在这种情况下,最好的顶部将如下所示:
Foreach
HashMap
HashSet
Stream
- 在这种情况下最好不要使用但是如果您需要处理大数据,那么最好的选择是使用基于 HashMap
的方法。
所以最好的顶部是这样的:
HashMap
HashSet
Stream
Foreach
答案 13 :(得分:0)
在 10,000,000 个随机元素的 排序 数组上测试,值在 0 到 200,000,000 之间。在具有 4GB 堆空间的 10 处理器 i9 上进行测试。两个数组的排序时间为 1.9 秒。
结果:
primitive() - 1.1 秒
public static int[] primitive(int[] a1, int[] a2) {
List<Integer> list = new LinkedList<>();
OfInt it1 = Arrays.stream(a1).iterator();
OfInt it2 = Arrays.stream(a2).iterator();
int i1 = it1.next();
int i2 = it2.next();
do {
if (i1==i2) {
list.add(i1);
i1 = it1.next();
}
if (i1 < i2) i1 = it1.next();
if (i2 < i1) i2 = it2.next();
} while(it1.hasNext() && it2.hasNext());
if (i1==i2) list.add(i1);
return list.stream().mapToInt(Integer::intValue).toArray();
}
boxed() - 6.8 秒
public static int[] boxed(int[] a1, int[] a2) {
return Arrays.stream(a1)
.filter(new HashSet<>(Arrays.stream(a2).boxed()
.collect(Collectors.toList()))::contains)
.toArray();
}