【问题标题】:How to Find Union of Two String Arrays如何找到两个字符串数组的并集
【发布时间】:2013-10-16 03:40:55
【问题描述】:

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

我需要使用循环来搜索第二个数组并找到重复项。我不断收到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;
}

【问题讨论】:

    标签: java arrays


    【解决方案1】:

    进行交集或并集的标准方法是使用集合。您应该使用集合框架中的Set 类。

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

    由于集合拥有独特的元素,集合形成了联合 两个数组。

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

    【讨论】:

      【解决方案2】:

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

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

      还有其他实用程序可以帮助完成类似的工作,例如番石榴:

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

      【讨论】:

        【解决方案3】:

        这部分代码有几个问题:

        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++ 不是外循环的一部分。你不需要i 和cnt;它们的值应始终匹配。最后,您将为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&lt;String&gt;,将两个数组中的元素相加,然后将结果转换回数组。

        【讨论】:

        • boolean = set2[m].equals(union[p]); - 你的意思可能是:found |= set2[m].equals(union[p]);
        • 感谢您的指导。这非常有帮助。我了解自己的错误,并且对如何纠正错误有了更好的了解。
        • @alfasin - 哎呀。感谢您指出了这一点。现在修好了。不过,不需要|=; = 会这样做,因为除非found 是false,否则不会输入循环体。
        • 对,我错过了 for 循环内的条件...+1 :)
        【解决方案4】:

        你在这一行得到 ArrayIndexOutOfBoundsException:

        union[i] = set2[m];
        

        因为你在某处不断增加i:set2.length * union.length 次(嵌套循环)。

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

        正确的做法是像 Deepak Mishra 建议的那样,使用 Set 来“处理”重复项。

        例子:

        int[] a = {1,2,3,4,5};
        int[] b = {4,5,6,7};
        Set union = new HashSet<Integer>();
        for(int i=0; i<a.length; i++) union.add(a[i]);
        for(int i=0; i<b.length; i++) union.add(b[i]);
        Object[] ans = union.toArray();
        for(int i=0; i<ans.length; i++)
            System.out.print(ans[i]+" ");
        

        将输出:

        1 2 3 4 5 6 7 
        

        因为它是硬件,所以我不会编写答案的代码,但我会给你一个提示:
        按照你的方式做需要O(n^2) - 如果你想一点,我相信您可以在更好的时间找到一种方法,例如,
        O(n log n)...

        【讨论】:

        • 谢谢!我很感激你的指导。这非常有帮助。
        【解决方案5】:

        虽然使用 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));
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多