如何查找n个排序字符串数组中的所有常见元素?

时间:2013-10-17 19:19:08

标签: java arrays

我有多个可变大小的字符串数组,这些数组是预先排序的,我需要查找每个数组中包含的所有元素。例如,如果我有数组

 {"cat", "dog", "horse"}, 
 {"dog", "donkey", "horse"},
 {"cat", "dog", "donkey", "horse"}

我希望结果数组为

{"dog", "horse"}

实现这一目标的有效方法是什么?

9 个答案:

答案 0 :(得分:1)

我将描述一个算法,假设数组按升序顺序排序

为3个数组中的每个数组创建一个索引,并将其设置为0.

确定数组索引处的哪个元素最小,并递增该数组的索引。

如果最小元素位于两个数组的开头,则表示您找到了重复元素。

你可以递增两个(全部)指数。

此算法应采用 O(n)时间。


数组可能有也可能不具有两个相同的元素。如果可能,您可能必须跟踪数组的前一个元素并将其与当前元素进行比较以找到那些重复项。

答案 1 :(得分:1)

给出三个数组

String[] arr1 = {"cat", "dog", "horse"};
String[] arr1 = {"dog", "donkey", "horse"};
String[] arr1 =  {"cat", "dog", "donkey", "horse"};

通过逐个迭代元素或按照

创建三个 Set
Set<String> set1 = new HashSet(Arrays.asList(arr1));
Set<String> set2 = new HashSet(Arrays.asList(arr2));
Set<String> set3 = new HashSet(Arrays.asList(arr3));

现在通过调用set interface

中给出的 retainAll 函数来执行set intersection
/* set1 intersection set2: results in set1 having only common elements */
set1.retainAll(set2);
/* Finally intersection of previous result and set3: final result in set1 */
set1.retainAll(set3);

有关java集合中支持的 Set 操作的更多信息,请参阅here

答案 2 :(得分:1)

这个怎么样......

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class CommonElements {
    public static void main(String[] args) {
        String[] one = {"cat", "dog", "horse"};
        String[] two = {"dog", "donkey", "horse"};
        String[] three = {"cat", "dog", "donkey", "horse"};

        List<String> result = findCommonElements(one, two, three);

        for (String s : result)
            System.out.println(s);
    }

    public static List<String> findCommonElements(String[] ... args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        for (String[] strings : args) {
            for (String s : strings) {
                Integer current = map.get(s);
                map.put(s, current == null ? 1 : current + 1);
            }
        }

        List<String> result = new LinkedList<String>();
        for (Entry<String, Integer> entry : map.entrySet())
            if (entry.getValue() == args.length)
                result.add(entry.getKey());

        return result;
    }
}

答案 3 :(得分:0)

set pointers to start
while no array exhausted
  max_value = max value over pointers
  for each array
    while value at pointer < max_value
      increment pointer
      if array exhausted
        exit program
  for each array
    if value at pointer != max_value
      continue // restart from line 3
  print max_value

答案 4 :(得分:0)

你肯定希望将多个数组保存在它自己的数组中,即:一个多维数组。那么你可以做的就是有第二个数组并循环遍历你的多个数组.....将每个可能的元素放入这个新数组......即:{cat,dog,horse,donkey}

完成此操作后,您可以遍历数组并将它们与所有元素的“主数组”进行比较。如果数组不包含主数组中的元素,请从master中删除该元素。最后,主数组将包含每个原始数组中的所有元素。我承认可能有一个更优雅的解决方案......但这会有效!

答案 5 :(得分:0)

我首先得到最大数组的长度,并将一个新的结果数组初始化为该长度。然后使用嵌套循环比较每个已创建的字符串数组中的元素,例如比较元素'猫','狗',猫。因为它们不相等,所以在最里面的数组中向上移动一个位置,比较'cat','dog','dog'等。如果元素的值在所有数组中相等,则将该元素添加到结果数组中

从那里你应该能够编写一个有效的解决方案。

答案 6 :(得分:0)

我喜欢关于集合交集的解决方案,但也想建议我:

final String array[][] = {
     {"cat", "dog", "horse"}, 
     {"dog", "donkey", "horse"},
     {"cat", "dog", "donkey", "horse"},
     // add more arrays here
     };

final HashMap <String, Integer> map = new HashMap<String, Integer>(array.length);
for (final String[] iArray : array)
    for (final String element: iArray)
    {
        if (map.containsKey(element))
            map.put(element, map.get(element) + 1);
        else
            map.put(element, 1);
    }

for (final String element: map.keySet())
    if (map.get(element) == array.length)
        System.out.println("keyword " + element + " exists in all arrays");

答案 7 :(得分:-1)

Arrays.asList(...).contains(...)。这允许您将数组转换为列表,只需查看数组是否包含元素而不必迭代它。如果是这样,继续检查其他数组以查看它是否是所有数组中的公共元素。

答案 8 :(得分:-2)

您可以将您的数组添加到java.util.Set,并在每个Set上调用方法contains。 (f.e set.contains("horse"));如果它包含相同的字符串,则会返回true,否则为false,然后检查所有结果。