我正在开发一个解读类型的程序,用户可以输入随机字母,程序会遍历字母和单词列表,尝试查找单词列表中包含这些部分或全部随机字母的单词。
例如:
if Input = "sasdfle"
words found in wordlist = "sad", "fleas", "flea", etc...
单词只能包含从用户输入的字母,并且每个字母都不能重复。我在这里找到了多个问题,找到了字谜,但我似乎无法找到一个算法来完成我上面所说的。
我不想在这里发布整个代码,但这是我遇到问题的主要部分:
答案 0 :(得分:3)
假设您拥有适当的英语单词集合,例如
private static HashSet<String> s_Words = new HashSet<String>() {
"abacus",
//...
"flea",
"fleas",
//...
"sad",
"sea",
// ...
"zoom",
};
您可以将其转换为更方便的聚合词典,其中键是一个初始字符串,其中所有字母都在其中排序("flea"
=&gt; {{1 },"aefl"
=&gt; "sad"
等)。如果两个或多个单词具有相同的键,则它们应组合到一个集合中,比如一个数组:
"ads"
您可以通过Linq实现这样的字典:
"ale", "lea" => "ael" : ["ale", "lea"]
然后给出一个字符串
private static Dictionary<String, String[]> s_Dict = s_Words
.Select(word => new {
Key = String.Concat(word.OrderBy(c => c)),
Value = word})
.GroupBy(item => item.Key, item => item.Value)
.ToDictionary(chunk => chunk.Key, chunk => chunk.ToArray());
您需要做的就是排序并只检查String Input = "sasdfle"
(256
)组合,包括并删除每个字母:
2 ** (length + 1) == 256
测试
string source = String.Concat(Input.OrderBy(c => c));
// all combinations of the set with empty one excluded, see
// http://stackoverflow.com/questions/30081908/c-sharp-linq-combinatorics-all-combinations-of-a-set-without-the-empty-set/30082360#30082360
var result = Enumerable
.Range(1, (1 << source.Length) - 1)
.Select(index => string.Concat(source.Where((item, idx) => ((1 << idx) & index) != 0)))
.SelectMany(key => {
String[] words;
if (s_Dict.TryGetValue(key, out words))
return words;
else
return new String[0]; })
.Distinct() // some words can be built in many ways
.OrderBy(word => word);
//.ToArray(); // if you want to represent words as array
将返回
Console.Write(String.Join(Environment.NewLine, result));