The Solution

A major hint is in the fact we are given a dictionary.  Because we are given this dictionary we can prep it in any way we like when the program starts, and then the processing of any word input becomes simple.  Most dictionaries will easily fit within memory of modern computing hardware, so this should not be a major concern.

So, having the dictionary, we have all possible valid word anagrams already.  The only trick is how to get from the input to these words.

So let’s think, “what do all anagrams have in common?”  For example, the word “post” has “pots”, “stop”, “tops”, etc.  It may seem obvious, but all anagrams have the same letters.  Thus, if we can hash or organize these letters in a consistent way, we can store all anagrams under the same key.  In this way, we can apply the same hash/organization to the input word, immediately get the list of anagrams, and simply exclude the input word from the anagram list.

The simplest way to do this would simply be to sort the letters, this is a fairly simple operation in C#:

var key = string.Concat(word.ToLower().OrderBy(c => c));

That would turn “post”, “pots”, etc. all into: “opst” which we can use as our key for our lookup.  Now, how to store them, you could download your own multidictionary, or create a Dictionary<string, List<string>>,but really C# already has one for you called a Lookup.  The Lookup stores a key to multiple values.

So first, let’s write a simple DAO for reading in our words from a file:

public class WordFileDao : IWordDao
{
public string FileName { get; private set; } public WordFileDao(string fileName)
{
FileName = fileName;
} public IEnumerable<string> RetrieveWords()
{
// make sure to remove any accidental space and normalize to lower case
return File.ReadLines(FileName).Select(l => l.Trim().ToLower());
}
}

Then, we can create an anagram finder to create the lookup on construction, and then find words on demand:

public class AnagramFinder
{
private readonly ILookup<string, string> _anagramLookup; public AnagramFinder(IWordDao dao)
{
// construct the lookup at initialization using the
// dictionary words with the sorted letters as the key
_anagramLookup = dao.RetrieveWords().ToLookup(
k => string.Concat(k.OrderBy(c => c)));
} public IList<string> FindAnagrams(string word)
{
// at lookup time, sort the input word as the key,
// and return all words (minus the input word) in the sequence
string input = word.ToLower();
string key = string.Concat(input.OrderBy(c => c)); return _anagramLookup[key].Where(w => w != input).ToList();
}
}

Notice the ToLookup() extension method (in System.Linq), this method creates an instance of Lookupfrom any IEnumerable<T> if you provide it a key generator and a value generator.  For the key generator, I’m returning the word in sorted, lowercase (for consistency).  For the value, I’m just lower-casing the word (again, for consistency).  This effectively creates the “dictionary of key to list of values” that, when you query using the “[…]” operator, will return an IEnumerable<T> of the values, or empty sequence if the key was not found.

And that’s it!  We have our anagram word finder which can lookup words quickly with only the cost of sorting the letters in a word, which is much less expensive (processing-wise) than attempting all permutations of the letters in a word.

Quote From:

Solution to Little Puzzlers–“List All Anagrams in a Word”

最新文章

  1. 连接SQLServer时,因启用连接池导致孤立事务的原因分析和解决办法
  2. POJ2942:Knights of the Round Table
  3. linux Mint 安装apache2
  4. Apple Pay 初探
  5. [python]数据整理,将取得的众多的沪深龙虎榜数据整一整
  6. ACM: 限时训练题解-Street Lamps-贪心-字符串【超水】
  7. 20145225《Java程序设计》 第6周学习总结
  8. visual studio F12 失效,可能是装了插件,比如ReSharper 但是,ReSharper没有激活导致.
  9. js解析或获取页面路径归纳
  10. R.id.layout等不能识别:cannot be resolved or is not a field
  11. Servlet的response输出到页面时乱码的解决方法
  12. [译]脱离jQuery,使用原生Ajax
  13. 第六百二十七天 how can I 坚持
  14. 《java入门第一季》之面向对象(修饰符的概念和总结)
  15. 第47节:Java当中的基本类型包装类
  16. 【转】python操作excel表格(xlrd/xlwt)
  17. ES6最新语法
  18. 【PAT】B1072 开学寄语(20 分)
  19. help2man: can&#39;t get `--help&#39; info from automake-1.15 Try `--no-discard-stderr&#39; if option outputs to stderr Makefile:3687: recipe for target &#39;doc/automake-1.15.1&#39; failed
  20. sqlserver 2008评估期已过

热门文章

  1. CDM业务单据,表体单价列赋值所需要注意的问题
  2. [Android笔记1]Activity+Layout+Button
  3. 使用Android网络编程实现简易聊天室
  4. ok6410 u-boot-2012.04.01移植五支持DM9000
  5. windows下使用命令查看端口占用情况
  6. Xamarin原生跨平台概述(精简概述,命中要害。PS:无图)
  7. ASP.NET MVC 异步Excel数据选择导出
  8. jsp-1 简单的应用servlet,并用其跳转页面
  9. CodeForces 384C Milking cows
  10. 利用fiddler将本地网页放到某个域下