anagram算法返回重复值

时间:2013-05-24 22:46:46

标签: java algorithm recursion anagram

我一直在开发一种算法来计算给定(一组)单词的字谜。我只是让它工作,有一个令人难以置信的令人沮丧的异常(没有双关语意图;没有抛出实际的异常)。尽管我尝试利用有效的“修剪”来减少重复次数,但我的算法是在主列表中添加副本,在这种情况下是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

感谢您的帮助! :)

5 个答案:

答案 0 :(得分:4)

明显的算法(只是交换字母)有点天真,并不认为相同的字母是同一个字母的实例。例如,如果你有一个像“前夕”这样的词,那么两个“e”是截然不同的;如果我们为了说明而加粗第一个E,你会在过程中的各个点获得“ e v e”和“e v e ”等组合。

你需要以某种方式消除重复。最简单的方法是将组合填充到一些类型的集合中(如HashSet)。它只能包含每个项目中的一个,因此副本将被有效地丢弃。

哦,使用String s,而不是StringBuilder s。我刚刚注意到你这样做了。 StringBuilder不会覆盖equals,因此您将继续使用从Object继承的版本。最终结果:仅当a时,对于两个StringBuilders ba.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