如何找到两个字符串数组的联合

我试图找到两个字符串数组的联合。 我创建了一个新数组,并将第一组中的所有数据复制到新数组中。 我无法将第二组中的信息添加到新数组中。

我需要使用循环来搜索第二个数组并找到重复项。 我一直得到一个ArrayIndexOutOfBoundsException

这是我目前的代码:

 static String[] union(String[] set1, String[] set2) { String union[] = new String[set1.length + set2.length]; int i = 0; int cnt = 0; for (int n = 0; n < set1.length; n++) { union[i] = set1[i]; i++; cnt++; } for (int m = 0; m < set2.length; m++) { for (int p = 0; p < union.length; p++) { if (set2[m] != union[p]) { union[i] = set2[m]; i++; } } } cnt++; union = downSize(union, cnt); return union; } 

做交叉或联合的标准方法是使用一套。 您应该使用集合框架中的Set类。

为两个数组创建两个arraylist对象。
定义Set对象。
使用addAll方法将两个arraylist对象添加到Set中。

由于set包含唯一元素,因此该集合形成两个数组的并集。

  //push the arrays in the list. List list1 = new ArrayList(Arrays.asList(stringArray1)); List list2 = new ArrayList(Arrays.asList(stringArray2)); HashSet  set = new HashSet (); //add the lists in the set. set.addAll(list1); set.addAll(list2); //convert it back to array. String[] unionArray = set.toArray(new String[0]); 

使用Set是最简单的方法之一:

 public static String[] unionOf(String[] strArr1, String[] strArr2) { Set result = new HashSet(); result.addAll(Arrays.asList(strArr1)); result.addAll(Arrays.asList(strArr2)); return result.toArray(new String[result.size()]); } 

还有其他可以帮助类似工作的实用程序,例如Guava:

 public static String[] unionOf(String[] strArr1, String[] strArr2) { return Sets.union(Sets.newHashSet(strArr1), Sets.newHashSet(strArr2)) .toArray(new String[0]); } 

这部分代码有几个问题:

 for(int m = 0; m < set2.length; m++) for(int p = 0; p < union.length; p++) if(set2[m] != union[p]) { union[i] = set2[m]; i++; } cnt++; 

首先,您应该使用!equals()而不是!=来比较字符串。 其次,尽管有缩进,但语句cnt++不是外循环的一部分。 你不需要icnt ; 他们的价值应始终匹配。 最后,为每个与它不同的union元素添加set2[m]一次。 您只想添加一次。 这是一个应该工作的版本:

 static String[] union( String[] set1, String[] set2 ) { String union[] = new String[set1.length + set2.length]; System.arraycopy(set1, 0, union, 0, set1.length); // faster than a loop int cnt = set1.length; for(int m = 0; m < set2.length; m++) { boolean found = false; for(int p = 0; p < union.length && !found; p++) { found = set2[m].equals(union[p]); } if(!found) { union[cnt] = set2[m]; cnt++; } } union = downSize( union, cnt ); return union; } 

正如其他海报所指出的,另一种方法是使用HashSet ,添加在两个数组中找到的元素,然后将结果转换回数组。

你在这一行得到ArrayIndexOutOfBoundsException:

 union[i] = set2[m]; 

因为你在某处继续增加: set2.length * union.length times(嵌套循环)。

做RJ写的东西不会给你工会 – 你会有很多重复的项目,因为通过这样做: set2[m].equals(union[p])你将set2 的每个成员与union的所有成员和每个成员进行比较它不等于 – 你添加它。 所以你最终多次添加相同的项目!

正确的做法就像Deepak Mishra使用Set建议的那样“照顾”副本。

例:

 int[] a = {1,2,3,4,5}; int[] b = {4,5,6,7}; Set union = new HashSet(); for(int i=0; i 

将输出:

 1 2 3 4 5 6 7 

因为它是HW我不会写答案的代码,但我会给你一个提示:
按照你的方式去做,需要O(n^2) - 如果你有点想,我肯定你可以找到一种方法在更好的时间做到这一点,比方说,
O(n log n) ......

尽管使用SETS是最佳解决方案,但这是一个简单的解决方案。

  private static String getUnion(String a, String b, boolean ignoreCase) { String union = ""; if (a == null || b == null || a.length() < 1 || b.length() < 1) { return union; } char[] shortest; char[] longest; if (ignoreCase) { shortest = (a.length() <= b.length() ? a : b).toLowerCase().toCharArray(); longest = (a.length() <= b.length() ? b : a).toLowerCase().toCharArray(); } else { shortest = (a.length() <= b.length() ? a : b).toLowerCase().toCharArray(); longest = (a.length() <= b.length() ? b : a).toLowerCase().toCharArray(); } StringBuilder sb = new StringBuilder(); for (char c : shortest) { for (int i = 0; i < longest.length; i++) { if (longest[i] == c) { sb.append(c); } } } union = sb.toString(); return union; } 

以下是一些测试。

 public static void main(String[] args) { System.out.println("Union of '' and BXYZA is " + getUnion("", "BXYZA", true)); System.out.println("Union of null and BXYZA is " + getUnion(null, "BXYZA", true)); System.out.println("Union of ABC and BXYZA is " + getUnion("ABC", "BXYZA", true)); System.out.println("Union of ABC and BXYZA is " + getUnion("ABC", "bXYZA", false)); }