我有一个返回Set<Set<String>>
的方法。在我的测试中,我尝试使用Set
方法检查预期的contains()
是否存在。
例如。 input = "cat", "dog", "god"
output = [[cat], [dog, god]]
现在,如果我output.contains(new HashSet<>(Arrays.asList("cat")))
,则会返回true
。
但如果我output.contains(new HashSet<>(Arrays.asList("dog", "god")))
,则返回false
。
根据我的理解,在两种情况下都应该返回true
。
我在这里缺少什么?
public class AnagramGroups {
public Set<Set<String>> group(Set<String> words) {
Set<Set<String>> groups = new HashSet<>();
for(String word: words) {
findAndAdd(word, groups);
}
return groups;
}
private void findAndAdd(String word, Set<Set<String>> groups) {
for(Set<String> group: groups) {
boolean found = false;
for(String str: group) {
if(isAnagram(str, word)) {
found = true;
}
break;
}
if(found) {
group.add(word);
return;
}
}
Set<String> set = new HashSet<>();
set.add(word);
groups.add(set);
}
private boolean isAnagram(String str, String word) {
Set<Character> characters = new HashSet<>();
for(char c: str.toCharArray()) {
characters.add(c);
}
for(char c: word.toCharArray()) {
if(!characters.contains(c)) {
return false;
}
characters.remove(c);
}
return characters.isEmpty();
}
public static void main(String[] args) {
Set<Set<String>> groups = new AnagramGroups()
.group(new HashSet<>(Arrays.asList("cat", "god", "dog")));
System.out.println(groups);
Set set1 = new HashSet<>(Arrays.asList("cat"));
Set set2 = new HashSet<>(Arrays.asList("god", "dog"));
System.out.println(groups.contains(set1));
System.out.println(groups.contains(set2));
groups.add(new HashSet<>(Arrays.asList("god", "dog")));
System.out.println(groups);
}
}
答案 0 :(得分:4)
问题出在findAndAdd
方法中,您正在改变外部group
(Set
)的元素(groups
),从而更改其{{1} }}。因此,hashCode()
找不到groups.contains(set2)
中存在的Set
,因为它在错误的存储桶(匹配新的groups
)而不是存储桶中查找它添加它(与原始hashCode()
匹配)。
您可以修改代码,方法是先从hashCode()
移除group
Set
,然后再对其进行修改,然后重新添加。
更改您的代码:
groups
为:
private void findAndAdd(String word, Set<Set<String>> groups) {
for(Set<String> group: groups) {
boolean found = false;
for(String str: group) {
if(isAnagram(str, word)) {
found = true;
}
break;
}
if(found) {
group.add(word);
return;
}
}
Set<String> set = new HashSet<>();
set.add(word);
groups.add(set);
}
当我尝试使用您的代码并进行更改时,我在两种情况下都获得了 private void findAndAdd(String word, Set<Set<String>> groups) {
for(Set<String> group: groups) {
boolean found = false;
for(String str: group) {
if(isAnagram(str, word)) {
found = true;
}
break;
}
if(found) {
groups.remove(group);
group.add (word);
groups.add(group);
return;
}
}
Set<String> set = new HashSet<>();
set.add(word);
groups.add(set);
}
。
输出:
true
答案 1 :(得分:0)
当您使用Set set2 = new HashSet<>(Arrays.asList("god", "dog"));
时,您未检查组合"god" and "dog"
,但检查每个元素god
,dog
或Set<Set<String>>
中存在cat
或groups contains `god` -> no
groups contains `dog` -> no
return false
不是,在你的集合中,你只有一个元素groups.stream().anyMatch(a -> a.equals(set2))// or groups.stream().anyMatch(set2::equals)
是分开的。它就像:
groups.stream().anyMatch(a -> a.containsAll(set2))
要解决您的问题,您可以使用等于:
a
或
4
答案 2 :(得分:0)
试试这个。
static String sort(String s) {
int[] sortedCP = s.codePoints().sorted().toArray();
return new String(sortedCP, 0, sortedCP.length);
}
public static Set<Set<String>> group(Set<String> words) {
Map<String, Set<String>> map = new HashMap<>();
for (String word : words)
map.computeIfAbsent(sort(word), k -> new HashSet<>()).add(word);
return new HashSet<>(map.values());
}
和
Set<String> words = new HashSet<>(Arrays.asList("cat", "dog", "god"));
System.out.println(group(words));
结果:
[[cat], [god, dog]]
中间变量map
有
{act=[cat], dgo=[god, dog]}