我一直在开发一种算法来计算给定(一组)单词的字谜。我只是让它工作,有一个令人难以置信的令人沮丧的异常(没有双关语意图;没有抛出实际的异常)。尽管我尝试利用有效的“修剪”来减少重复次数,但我的算法是在主列表中添加副本,在这种情况下是final static ArrayList(StringBuilder)()类型的对象。 I似乎无法弄清楚为什么会这样。以下是我的代码;我决定发布整个方法以方便。
这是学校的作业,而不是直接的答案/解决方案,我正在寻找指导/概念错误。
编辑:(编辑代码以避免在作业截止日期之前可能出现抄袭。)
以下是一个例子:
**input:**
pnxish
bauelqbs
coxiuqit
elbarcbs
ptos
**output:**
Now printing anagrams:
Anagram #0: sphinx
Anagram #1: squabble
Anagram #2: squabble
Anagram #3: quixotic
Anagram #4: quixotic
Anagram #5: scrabble
Anagram #6: scrabble
Anagram #7: pots
Anagram #8: post
Anagram #9: tops
Anagram #10: opts
Anagram #11: spot
Anagram #12: stop
感谢您的帮助! :)
答案 0 :(得分:4)
明显的算法(只是交换字母)有点天真,并不认为相同的字母是同一个字母的实例。例如,如果你有一个像“前夕”这样的词,那么两个“e”是截然不同的;如果我们为了说明而加粗第一个E,你会在过程中的各个点获得“ e v e”和“e v e ”等组合。
你需要以某种方式消除重复。最简单的方法是将组合填充到一些类型的集合中(如HashSet)。它只能包含每个项目中的一个,因此副本将被有效地丢弃。
哦,使用String
s,而不是StringBuilder
s。我刚刚注意到你这样做了。 StringBuilder
不会覆盖equals
,因此您将继续使用从Object
继承的版本。最终结果:仅当a
时,对于两个StringBuilders b
和a.equals(b)
,a == b
。
答案 1 :(得分:3)
一个简单的解决方案是使用Set
来存储你的字谜。这将处理重复的值。
我猜您正在使用列表,因为您的变量名为anagramList
。您可以在此处找到Set
的JavaDoc:http://docs.oracle.com/javase/6/docs/api/java/util/Set.html
答案 2 :(得分:2)
我希望使用Set来存储anagrams,但是使用String而不是StringBuilder,即
Set<String> anagrams = new HashSet<String>();
不使用StringBuilder的原因是hashCode在更改时不会改变,如下例所示:
StringBuilder sb = new StringBuilder();
System.out.println(sb.hashCode());
sb.append('c');
System.out.println(sb.hashCode());
这将输出相同的哈希码,这意味着StringBuilder的哈希码对于其内容而言不是可靠的比较器。
答案 3 :(得分:1)
这是您在代码中遇到的问题。如果列表中存在“争吵”的StringBuilder对象,则在您再次构建“争吵”后检查列表是否包含“争吵”的不同StringBuilder对象时,contains方法将返回false(由于字母b而发生)发生两次)。
包含正在检查对象是否在列表中,而不是是否存在表示相同字符串的对象。
答案 4 :(得分:0)
您无法使用contains()方法检查字符串内容本身是否在其中:
List<StringBuilder> list = new ArrayList<StringBuilder>();
StringBuilder sb = new StringBuilder("hello");
list.add(sb);
StringBuilder sb2 = new StringBuilder("hello");
System.out.println(list.contains(sb2));
//echos false