C# 所有字母组合(n项)符合模式
我试图解密一个单词,其中的字母被随机替换为其他字母(但不是两个不同的字母变成同一个) 目标:C# 所有字母组合(n项)符合模式,c#,linq,pattern-matching,combinations,populate,C#,Linq,Pattern Matching,Combinations,Populate,我试图解密一个单词,其中的字母被随机替换为其他字母(但不是两个不同的字母变成同一个) 目标: 我正在搜索一个已知长度和字母模式的单词 我所知道的: 模式本身意味着如果搜索“来宾”,我知道“123454”,它显示了这个单词中唯一字母的位置。当然,我知道这是一个正确书写的英语单词 软件端: 我已经创建了一个DataGridView,它的标题由模式命名。我想用所有字母的可能组合填充每个列(模式) 我所尝试的: Ill start at end=>我已经成功实现了一个拼写检查器。所以在最后我考虑了一下,
我正在搜索一个已知长度和字母模式的单词 我所知道的:
模式本身意味着如果搜索“来宾”,我知道“123454”,它显示了这个单词中唯一字母的位置。当然,我知道这是一个正确书写的英语单词 软件端:
我已经创建了一个
DataGridView
,它的标题由模式命名。我想用所有字母的可能组合填充每个列
(模式)
我所尝试的:Ill start at end=>我已经成功实现了一个拼写检查器。所以在最后我考虑了一下,只需浏览一下这些列,检查每个结果,就可以找到真正的单词 从一开始我就写了这篇文章:
private string[] alpha = new string[] { "a", "b", "c", ..."z"};
private int[] digits = new int[] { 0, 1, 2, 3, 4,....9 };
private void bruteforce()
{
// Each Column
foreach(DataGridViewColumn col in dgvResults.Columns)
{
// HeaderText to CharArray to IntArray (-48 to switch from ASCII to INT).
int[] pattern = Array.ConvertAll(col.HeaderText.ToCharArray(), c => c - 48);
// Prepare an result-array with the same length as the pattern.
string[] resultSet = Enumerable.Repeat("-", pattern.Length).ToArray();
// For each digit 0-9.
foreach(int digit in digits)
{
// In pattern search for each digit and save the index.
int[] indexes = pattern.FindAllIndexof(digit);
// If index is found.
if(indexes.Length > 0)
{
// Custom function ReplaceAtIndex.
// Replace resultSet-Values at given Indexes with unique letter
resultSet.ReplaceAtIndex(indexes, alpha[digit]);
}
}
}
}
当前结果:0112344
的模式将被保存(resultSet
)为abbcdee
现在我需要在保持相同模式的同时循环字母 这一步感觉比以前更复杂。我想,在继续吹我的头之前,我要看看stackoverflow上是否有一些天才可以提供一种更简单的方法(也许是LINQ的一些捷径) 那么,请问,有没有人能帮我做这件事呢?
我感谢这里的一切帮助。谢谢这是一个非常有效的算法,可以生成您想要的内容 这是我在和中使用的算法的一个变体,经过优化以执行最小分配
public static class Algorithms
{
private static readonly char[] alpha = Enumerable.Range('a', 'z' - 'a' + 1).Select(c => (char)c).ToArray();
public static IEnumerable<string> GenerateWords(this string pattern)
{
return pattern.GenerateWordsCore().Select(word => new string(word));
}
public static IEnumerable<char[]> GenerateWordsCore(this string pattern)
{
var distinctSet = pattern.Select(c => c - '0').Distinct().ToArray();
var indexMap = pattern.Select(c => Array.IndexOf(distinctSet, c - '0')).ToArray();
var result = new char[pattern.Length];
var indices = new int[distinctSet.Length];
var indexUsed = new bool[alpha.Length];
for (int pos = 0, index = 0; ;)
{
// Generate the next permutation
if (index < alpha.Length)
{
if (indexUsed[index]) { index++; continue; }
indices[pos] = index;
indexUsed[index] = true;
if (++pos < distinctSet.Length) { index = 0; continue; }
// Populate and yield the result
for (int i = 0; i < indexMap.Length; i++)
result[i] = alpha[indices[indexMap[i]]];
yield return result;
}
// Advance to next permutation if any
if (pos == 0) yield break;
index = indices[--pos];
indexUsed[index] = false;
index++;
}
}
}
Eric Lippert有一组关于这方面的博客帖子,可以帮助你获得n个字母的所有组合,然后你可以使用他的帖子获得所有方法来排列n个字母,并将它们应用到你的模式中。好的。到目前为止,还不错。对“12345678”的测试不会返回任何结果。它肯定列出了一系列的组合。但是有没有可能还有一些呢?如果是,为什么?结果计数为156275。我用NHuspell(美国英语)检查了拼写。我知道这个模式表示这个单词中有8个不同的字母。是的,对不起,有一个问题,我的算法是生成组合,但你真正需要的是唯一的排列。别担心,我会调整它并发布更新。
foreach(字符串单词在“1234.GenerateWords()”中)=>如果word.Contains(“th”)
甚至没有返回一次命中。“这个”或“那个”或“然后”或“他们”怎么样?哦,好的。非常感谢:)。顺便提一下很荣幸能在这么短的时间内写出这样的代码。@C4ud3x花了比预期多一点的时间,但现在应该可以了(我希望:)
bool test = "12334".GenerateWords().Contains("hello");
foreach (var word in "123454".GenerateWords())
{
// Do something with word
}