我想消除存储在列表列表中的重复键组合,并希望以有效的方式删除或标记重复项。让我用一个简单的例子来解释这个问题。我有一个列表,其中包含名称的一部分作为列表中的单独元素。一个人的名字中可以有2 - n个部分。
基本列表中的元素包含人名的部分,可以按任何顺序出现,在这种情况下,它有三个部分{“Rajesh”,“Kumar”,“Singh”}。 类似地,可以有一个人名列表,其名称按任何顺序出现,如下所示
0 = { "Rajesh", "Kumar", "Singh" }
1 = { "William", "Robert" }
2 = { "John", "Anderson", "Jr" }
3 = { "Kumar", "Rajesh", "Singh" }
上面列表中的项目编号3需要被删除,因为它中只有3个项目,并且部分与项目0匹配,尽管它们的外观顺序不同。
谢谢
答案 0 :(得分:1)
将元素存储在Set<Set<String>>
中。集合是无序的,因此查找不关心组内的原始顺序。 Set.equals
:
将指定对象与此集进行相等性比较。返回true 如果指定的对象也是一个集合,则两个集合具有相同的值 size,并且指定集的每个成员都包含在此集合中 (或者等效地,该组的每个成员都包含在 指定的集合)。此定义确保equals方法有效 正确地跨越集合接口的不同实现。
答案 1 :(得分:0)
有效地执行此操作的一种方法是为集合编写包装类,并为其定义自定义哈希策略:
class KeyCombinationWrapper {
private final List<String> keys;
public KeyCombinationWrapper(List<String> keys) {
this.keys = new ArrayList<>(keys);
}
public List<String> getKeys() {
return keys;
}
@Override
public boolean equals(Object obj) {
// Compare lists of keys in an order-independent way, for example,
// by calling containsAll on both sides.
...
}
@Override
public int hashCode() {
// Hash code must be computed in an order-independent way,
// for example by adding up or XOR-ing hash codes of individual keys.
...
}
}
将每个密钥集的KeyCombinationWrapper
个对象添加到HashSet<KeyCombinationWrapper>
,然后从保留在最终集合中的包装器中获取唯一密钥。
只要您遵循指南,这两种方法的实施细节由您决定。
答案 2 :(得分:0)
您可以使用String.hashCode()方法将每个部分汇总为long,然后xor每个部分的值以获得表示所有部分的摘要,而不考虑顺序。
然后浏览列表,在遇到每个元素时保留组合哈希值和值的HashMap。如果组合的散列键已经存在,则决定是保留新的还是旧的。
完成后从HashMap转储值。
答案 3 :(得分:0)
我建议你制作一个单词及其索引的反向映射。
Map<String, Integer[]>
应该有用。
对于每个索引,检查地图中是否存在具有相同索引值的所有单词。如果他们这样做,那么这是一个重复的名称,你忽略了这一点。 如果没有,请更新地图。
这将是O(numNames*totalWordsinNames)