有啥简单的方法可以判断单词列表是不是是彼此的字谜?
Posted
技术标签:
【中文标题】有啥简单的方法可以判断单词列表是不是是彼此的字谜?【英文标题】:What is an easy way to tell if a list of words are anagrams of each other?有什么简单的方法可以判断单词列表是否是彼此的字谜? 【发布时间】:2010-10-06 01:06:19 【问题描述】:你会如何列出互为变位词的单词?
我在申请目前的工作时被问到这个问题。
orchestra
可以重新排列成carthorse
,所有原始字母只使用一次,因此这些词是彼此的字谜。
【问题讨论】:
嘿!我们向我们采访的每一位程序员提出这个问题!你在为我们破坏一切! @Jim In Texas:这个问题并没有破坏你的面试策略,它揭示了面试策略存在根本性的缺陷。就像根据他穿的颜色工作服来挑选机械师一样。将您总是选择蓝色工作服的知识泄露给新候选人并不会破坏您的机械挑选策略。它揭示了它是一种非策略,因为它可以被没有编程知识的人破坏。 我发现很难想象“没有编程知识的人”能够站在白板上编写程序来检测字谜。这实际上是一个非常好的初始屏幕问题,原因有很多。真的,如果候选人有足够的兴趣阅读这个 SO 问题,那是一件好事! 【参考方案1】:将所有字母按字母顺序放入字符串中(排序算法),然后比较结果字符串。
【讨论】:
是的,这几乎就是我想出的……也得到了这份工作! 有一种替代算法涉及计算每个单词中的字符。它更快,但对于 Unicode 单词来说会更昂贵。 我曾考虑过这一点,但是您必须比较生成的字母计数数组、散列或其他 - 对于短字谜,我的算法可能更快,但对于较大的字谜,您的可能会更快.会是一个有趣的测试... 您不需要比较所有地图 - 只需为第一个单词获取一个地图,然后为所有其他单词查看它们是否 匹配 相同的地图,即迭代他们的字母并在地图副本中减少它们。最后你找到了所有的字母,地图计数必须归零。 我明白你在说什么。但是地图有26个位置。一旦你完成了增量/减量,你必须经过 26 次比较到 0 来验证地图匹配。我必须做更多的研究才能找出哪种方法需要更多的比较——尽管与 0 的比较更便宜......【参考方案2】:幸好我们都生活在 C# 现实中,即在内存不足的四核机器上对短词进行就地排序。 :-)
但是,如果您碰巧受到内存限制并且无法触及原始数据,并且您知道这些单词包含 ASCII 表下半部分的字符,您可以采用不同的算法来计算每个单词的出现次数每个单词中的字母而不是排序。
如果您想在 O(N) 中执行该算法并且不关心内存使用情况(每个 Unicode 字符的计数器可能非常昂贵),您也可以选择该算法。
【讨论】:
【参考方案3】:对每个元素进行排序(删除空格)并与前一个元素进行比较。如果它们都相同,它们都是字谜。
【讨论】:
标点符号我可以理解,对于带有撇号的单词,但是空格?我不知道很多带有空格的单词...我认为为了进行这样的简单练习,您可以放心地假设这些单词仅包含字母。 当呈现为谜题时,字谜通常分布在整个短语中。所以你编写的例程要健壮。【参考方案4】:有趣的是,Eric Lippert's Fabulous Adventures In Coding Blog 于 2009 年 2 月 4 日在this post 中处理了这个问题的变体。
【讨论】:
死链接,archive.org 来救援:web.archive.org/web/20190119000458/https://…【参考方案5】:以下算法应该可以工作:
对每个单词中的字母进行排序。
对每个列表中已排序的字母列表进行排序。
比较每个列表中的每个元素是否相等。
【讨论】:
对字母列表进行排序后,您可以将第一个字母与最后一个字母进行比较,而不是逐个进行比较。如果第一个和最后一个相同,那么它们都是相等的。 @EricNess 你确定吗?考虑输入:“abbc”和“abcc”。相同的长度,相同的第一个和最后一个字符......或者我误解了你的评论。【参考方案6】:对列表中的单词进行排序。
如果 abc、bca、cab、cba 是输入,则排序后的列表将是 abc、abc、abc、abc。
现在他们所有的哈希码都是相等的。比较哈希码。
【讨论】:
【参考方案7】:首先想到的是对字母进行排序和比较(逐个字母、字符串比较……)。
【讨论】:
【参考方案8】:-
比较长度(如果不相等,则没有机会)
制作字符串长度的位向量
对于第一个字符串中的每个
char
,在第二个字符串中查找它的出现
设置第一次未设置的位
如果你能找到失败的一站
【讨论】:
【参考方案9】:public static void main(String[] args)
String s= "abc";
String s1="cba";
char[] aArr = s.toLowerCase().toCharArray();
char[] bArr = s1.toLowerCase().toCharArray();
// An array to hold the number of occurrences of each character
int[] counts = new int[26];
for (int i = 0; i < aArr.length; i++)
counts[aArr[i]-97]++; // Increment the count of the character at respective position
counts[bArr[i]-97]--; // Decrement the count of the character at respective position
// If the strings are anagrams, then counts array will be full of zeros not otherwise
for (int i = 0; i<26; i++)
if (counts[i] != 0)
return false;
【讨论】:
【参考方案10】:经过尝试的 anagram 哈希码逻辑给了我错误的输出
public static Boolean anagramLogic(String s,String s2)
char[] ch1 = s.toLowerCase().toCharArray();
Arrays.sort(ch1);
char[] ch2= s2.toLowerCase().toCharArray();
Arrays.sort(ch2);
return ch1.toString().hashCode()==ch2.toString().hashCode(); //wrong
纠正这个代码,下面是我看到的唯一选项,感谢任何建议
char[] ch1 = s.toLowerCase().toCharArray();
Arrays.sort(ch1);
char[] ch2= s2.toLowerCase().toCharArray();
Arrays.sort(ch2);
return Arrays.equals(ch1,ch2);
【讨论】:
以上是关于有啥简单的方法可以判断单词列表是不是是彼此的字谜?的主要内容,如果未能解决你的问题,请参考以下文章