我通常不會這樣做,但我想出了一個更好的解決方案來解決您的問題,它值得自己回答!這個AnagramSolver
解決方案比我的其他答案更優化,因爲它不會創建單詞的每一個單一置換,並且字典查找是非常優化的。試試看:
用法示例:
string[] dictionary = ReadDictionary(...);
var solver = new AnagramSolver(dictionary);
int minimumLength = 1;
IEnumerable<string> results = solver.SolveAnagram("AEMNS", minimumLength);
// Output the results:
foreach (var result in results)
{
Console.WriteLine(result);
}
// Output example:
// "NAMES", "MANES", "MEANS", "AMEN", "MANE", "MEAN", "NAME", "MAN", "MAE", "AM", "NA", "AN", "MA", "A",
代碼:
public class AnagramSolver
{
public AnagramSolver(IEnumerable<string> dictionary)
{
// Create our lookup by keying on the sorted letters:
this.dictionary = dictionary.ToLookup<string, string>(SortLetters);
}
private ILookup<string, string> dictionary;
public IEnumerable<string> SolveAnagram(string anagram, int minimumLength)
{
return CreateCombinations(anagram, minimumLength)
// Sort the letters:
.Select<string, string>(SortLetters)
// Make sure we don't have duplicates:
.Distinct()
// Find all words that can be made from these letters:
.SelectMany(combo => dictionary[combo])
;
}
private static string SortLetters(string letters)
{
char[] chars = letters.ToCharArray();
Array.Sort(chars);
return new string(chars);
}
/// <summary> Creates all possible combinations of all lengths from the anagram. </summary>
private static IEnumerable<string> CreateCombinations(string anagram, int minimumLength)
{
var letters = anagram.ToCharArray();
// Create combinations of every length:
for (int length = letters.Length; length >= minimumLength; length--)
{
yield return new string(letters, 0, length);
// Swap characters to form every combination:
for (int a = 0; a < length; a++)
{
for (int b = length; b < letters.Length; b++)
{
// Swap a <> b if necessary:
char temp = letters[a];
if (temp != letters[b]) // reduces duplication
{
letters[a] = letters[b];
letters[b] = temp;
yield return new string(letters, 0, length);
}
}
}
}
}
}
這裏的算法摘要:
的基本思想是,每一套字謎從派生同一組字母。
如果我們對字母進行排序,我們可以將多組字形組合在一起。
我從Algorithm for grouping anagram words得到了這個想法。
例如,可以在「AEMNS」上鍵入一組字符(「NAMES」,「MANES」,「MEANS」)。
因此,一旦我們創建了我們的字典查找,解決這個咒語的過程非常簡單快捷 - 只需對字謎的字母進行排序並執行查找即可。
下一個挑戰是找到所有「較小」的字謎 - 例如,找到「名稱」,「SANE」,「MAN」,「AN」,「A」等。
這可以通過發現所有組合的謎語。
組合比排列更容易找到。不需要遞歸。我用3個循環和簡單的交換實現了完整的組合!花了一段時間纔算正確的算法,但現在它已經被清理乾淨了,非常漂亮。
對於找到的每個組合,我們必須再次對這些字母進行排序並執行查找。
這給了我們所有可能的解決方案的字謎!
你忘記了「家庭作業」標籤嗎? –
即使您沒有任何代碼包含在您的問題中,您是否可以顯示您嘗試創建的算法的一些示例輸入和輸出? – CoderDennis
@Muad這不是一門功課..即時通訊練習如何編程以及.. 樣品輸入: 模式:2V-5C 快報:AOLPNMC 組合: AOL OLP PAL PAN ... PLAM PALM等..被發現 接話: PALM 計劃 ...這將列出所有在系統詞典中找到的話..比較生成到系統字典中的所有組合,如果匹配則它將被列在Words Found Listbox中。 .. – Rex