检查完全包含在其他字符串列表中的字符串列表

时间:2017-01-29 16:56:38

标签: java string list linked-list

我编写了这段代码来检查字符串列表是否完全包含在另一个字符串中,在这种情况下删除列表。

public static void main(String[] args) {
    LinkedList<String> l1 = new LinkedList<String>();
    LinkedList<String> l2 = new LinkedList<String>();
    l1.add("Cc");
    l1.add("Dd");
    l2.add("Cc");
    l2.add("Dd");
    l2.add("Ee");
    LinkedList<LinkedList<String>> l = new LinkedList<LinkedList<String>>();
    l.add(l1);
    l.add(l2);
    System.out.println("OUTPUT: " + filterSublist(l));

}

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) {
    List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l);
    l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.contains(x)));
    return uniq;
}

函数filterSubList应该返回一个字符串列表列表,该列表没有完全包含在其他列表中的列表。 在我们的例子中:

  • 清单1:“Cc,Dd”
  • 清单2:“Cc,Dd,Ee”

由于列表1完全包含在列表2中,因此该函数应返回仅包含列表2的列表列表。 但是当我运行程序时,我得到的输出是一个包含两者的列表:

OUTPUT: [[Cc, Dd], [Cc, Dd, Ee]]

这是错误的。 filterSubList函数中有错误吗?

2 个答案:

答案 0 :(得分:1)

您正在检查包含另一个列表(对象)的一个列表(对象)。每当创建一个新对象时,新的列表将在内存中以不同的方式分配,而是使用containsAll检查其中的对象:

请改为尝试:

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) {
List<LinkedList<String>> uniq = new LinkedList<LinkedList<String>>(l);
l.forEach(elem -> uniq.removeIf(x -> !x.equals(elem) && elem.containsAll(x)));
return uniq;
}

如果Rene提出了与OP相关的一些观点,那么这个实现几乎跟随他的主导,但是以不同的方式。

static List<LinkedList<String>> filterSublistAlternate(LinkedList<LinkedList<String>> l) {
boolean[] removed = new boolean[ l.size() ]; 
outer: for(int i=0; i< l.size() ; i++)
    inner: for(int j=0; j< l.size() ; j++)
    {
        if( i != j )
        if(l.get(j).containsAll(l.get(i)))
        {
            System.out.println(i+" and "+j);
            if(l.get(i).size() == l.get(j).size())
                if(removed[i] == removed[j] && !removed[i])
                    removed[i] = true;
                else
                    continue outer;
            else
            {
                removed[i] = true;
                continue outer;
            }

        }
    }

for(int i=removed.length-1; i>=0  ; i--)
    if(removed[i])
        l.remove(i);

return l;
}

答案 1 :(得分:0)

我提出以下解决方案:

  • 内存效率更高,因为它不会复制原始列表
  • 更正确,因为它确实检查了子列表(不仅仅是单个元素存在)
  • 更正确,因为它会从结果中删除重复项

代码:

static List<LinkedList<String>> filterSublist(LinkedList<LinkedList<String>> l) {
    return l.stream()
        .filter(x -> l.stream().noneMatch(elem -> !elem.equals(x) && Collections.indexOfSubList(elem, x) != -1))
        .distinct()
        .collect(Collectors.toList());
}