Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在linkedlist of String中查找重复项的最有效方法-java_Java_Linked List_Duplicates - Fatal编程技术网

在linkedlist of String中查找重复项的最有效方法-java

在linkedlist of String中查找重复项的最有效方法-java,java,linked-list,duplicates,Java,Linked List,Duplicates,假设我们有一个linkedlist of linkedlist of String LinkedList<LinkedList<String>> lls = new LinkedList<LinkedList<String>> (); LinkedList<String> list1 = new LinkedList<String>(Arrays.asList("dog", "cat", "snake")); LinkedL

假设我们有一个linkedlist of linkedlist of String

LinkedList<LinkedList<String>> lls = new LinkedList<LinkedList<String>> ();
LinkedList<String> list1 = new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
LinkedList<String> list2 = new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
LinkedList<String> list3 = new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
lls.add(list1);
lls.add(list2);
lls.add(list3);
LinkedList lls=newlinkedlist();
LinkedList list1=新的LinkedList(Arrays.asList(“狗”、“猫”、“蛇”));
LinkedList list2=新的LinkedList(Arrays.asList(“驴子”、“狐狸”、“狗”));
LinkedList list3=新的LinkedList(Arrays.asList(“horse”、“cat”、“pig”));
lls.add(列表1);
lls.add(列表2);
lls.add(清单3);
如您所见,这3个linkedlist的字符串是不同的,但也有一些共同的元素。 我的目标是编写一个函数,将每个列表和其他列表进行比较,如果至少有一个相同的元素(dog在list1和list2中),则返回TRUE,否则返回FALSE

我认为我需要做的第一件事是比较列表中所有可能的排列,列表之间的比较是逐元素的。 我不确定这是最有效的方法。
您能提出一个最终最有效的想法吗?

将所有列表中的所有项目添加到一个列表中,然后对其进行排序(
Collections.sort
)。然后遍历它并检查重复项

例如

ArrayList list=new ArrayList();
list.addAll(列表1);//再加上其他的
集合。排序(列表);
用于(字符串s:列表){
如果(该项与上一项相同){
返回true;
}
}

将所有列表中的所有项目添加到一个列表中,然后对其进行排序(
Collections.sort
)。然后遍历它并检查重复项

例如

ArrayList list=new ArrayList();
list.addAll(列表1);//再加上其他的
集合。排序(列表);
用于(字符串s:列表){
如果(该项与上一项相同){
返回true;
}
}
使用retainal()

for(最终链接列表ll:lls)
{
清单1.保留(ll);
}
System.out.println(“list1=“+list1”);
使用retainal()

for(最终链接列表ll:lls)
{
清单1.保留(ll);
}
System.out.println(“list1=“+list1”);

LinkedList不是检测重复项的最佳集合。若可以,试着使用HashSet,但若不能做到这一点,仍然可以将列表中的所有元素放到一个集合中。哈希集包含没有重复项的元素,因此,如果列表大小中存在重复的元素,哈希集包含的元素将少于所有列表。

LinkedList不是检测重复项的最佳集合。若可以,试着使用HashSet,但若不能做到这一点,仍然可以将列表中的所有元素放到一个集合中。Hashset包含没有重复项的元素,因此如果列表大小中有重复的元素,Hashset的元素将比所有列表包含的元素都少。

假设给定的列表不应通过删除元素或对其排序(顺便说一句,其复杂性为O(nlogn))来更改,您基本上需要一个函数作为“构建块”对于实际的解决方案。即,检查一个集合是否包含另一个集合中包含的任何元素的函数

当然,这可以通过在第二个集合上使用
Collection#contains
来解决。但是对于某些集合(特别是列表),这有O(n),并且检查的总运行时间将是O(n*n)

为了避免这种情况,您可以创建一个包含第二个集合的所有元素的
集合。对于
集合
包含
方法保证为O(1)

然后,使用
Stream#anyMatch
,可以方便地进行实际检查:

containing.stream().anyMatch(e -> set.contains(e))
所以完整的例子可以是

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class DuplicatesInLinkedLists
{
    public static void main(String[] args)
    {
        LinkedList<LinkedList<String>> lls =
            new LinkedList<LinkedList<String>>();
        LinkedList<String> list1 =
            new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
        LinkedList<String> list2 =
            new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
        LinkedList<String> list3 =
            new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
        lls.add(list1);
        lls.add(list2);
        lls.add(list3);

        checkDuplicates(lls);
    }

    private static void checkDuplicates(
        List<? extends Collection<?>> collections)
    {
        for (int i = 0; i < collections.size(); i++)
        {
            for (int j = i + 1; j < collections.size(); j++)
            {
                Collection<?> ci = collections.get(i);
                Collection<?> cj = collections.get(j);
                boolean b = containsAny(ci, cj);
                System.out.println(
                    "Collection " + ci + " contains any of " + cj + ": " + b);
            }
        }
    }

    private static boolean containsAny(Collection<?> containing,
        Collection<?> contained)
    {
        Set<Object> set = new LinkedHashSet<Object>(contained);
        return containing.stream().anyMatch(e -> set.contains(e));
    }
}
如果列表中的元素对我来说是可修改的,那么你可以写

lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));
lists.add(新的ArrayList(Arrays.asList(“dog”、“cat”、“snake”));

或者,类似地,使用
LinkedList
而不是
ArrayList
,但是对于这个略图化的用例,我无法想象为什么会有强烈的理由故意使用
LinkedList

假设给定的列表不应该通过删除元素或对它们进行排序(其中有O(nlogn))来更改顺便说一句,复杂度),您基本上需要一个函数作为实际解决方案的“构建块”,即检查一个集合是否包含另一个集合中包含的任何元素的函数

当然,这可以通过对第二个集合使用
Collection#contains
来解决。但是对于某些集合(尤其是列表),这有O(n),并且检查的总运行时间为O(n*n)

为了避免这种情况,您可以创建一个包含第二个集合的所有元素的
Set
。对于
Set
contains
方法保证为O(1)

然后,使用
Stream#anyMatch
,可以方便地进行实际检查:

containing.stream().anyMatch(e -> set.contains(e))
所以完整的例子可以是

import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class DuplicatesInLinkedLists
{
    public static void main(String[] args)
    {
        LinkedList<LinkedList<String>> lls =
            new LinkedList<LinkedList<String>>();
        LinkedList<String> list1 =
            new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
        LinkedList<String> list2 =
            new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
        LinkedList<String> list3 =
            new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
        lls.add(list1);
        lls.add(list2);
        lls.add(list3);

        checkDuplicates(lls);
    }

    private static void checkDuplicates(
        List<? extends Collection<?>> collections)
    {
        for (int i = 0; i < collections.size(); i++)
        {
            for (int j = i + 1; j < collections.size(); j++)
            {
                Collection<?> ci = collections.get(i);
                Collection<?> cj = collections.get(j);
                boolean b = containsAny(ci, cj);
                System.out.println(
                    "Collection " + ci + " contains any of " + cj + ": " + b);
            }
        }
    }

    private static boolean containsAny(Collection<?> containing,
        Collection<?> contained)
    {
        Set<Object> set = new LinkedHashSet<Object>(contained);
        return containing.stream().anyMatch(e -> set.contains(e));
    }
}
如果列表中的元素对我来说是可修改的,那么你可以写

lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));
lists.add(新的ArrayList(Arrays.asList(“dog”、“cat”、“snake”));

或者,类似地,使用
LinkedList
而不是
ArrayList
,但是对于这个略图化的用例,我无法想象为什么会有强烈的理由故意使用
LinkedList

假设您想要使用LinkedList并且不允许转换到另一个数据结构,那么您可以做的就是创建一个me接受可变数量的链接列表的方法。从那里您希望获取所有唯一的链接列表组合,然后比较这些链接列表之间的所有唯一元素,如果您发现一个公共元素,请将该对链接列表标记为公共。您希望如何跟踪/返回数据(例如,一组具有共同元素的linkedlist对)取决于输出的外观,但这是我将使用的代码的一般结构。

假设您希望使用linkedlist,并且不允许转换为其他数据类型