所有 letter-combinations (n-items) 根据模式
All letter-combinations (n-items) according pattern
我正在尝试解密一个单词,其中的字母已被随机替换为其他字母(但不是将 2 个不同的字母替换为同一个字母)。
目标:
我正在搜索一个长度为 letter-pattern 的词。
我知道的:
该模式本身意味着如果搜索 "guests" 我知道“123454”,它显示了这个词中唯一字母的位置。我肯定知道它是一个正确书写的英文单词。
软件端:
我创建了一个 DataGridView
,其中 headers 以模式命名。我想用所有字母 a-z
.
的可能组合填充每个 Column
(模式)
我试过的:
我从最后开始 => 我已经成功实现了 spell-checker。所以最后我考虑只浏览这些列并检查每个结果以找到实际的单词。
从我看到的起点到目前为止我已经写了这个:
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
.
现在我需要在保持相同模式的同时循环字母。
这一步感觉比前面的更复杂。我想,在继续让我大吃一惊之前,我要看看 Whosebug 上是否有一些天才可以提供更简单的方法(也许是 LINQ 的一些快捷方式)。
所以,请问有没有人在想 "easy doin" 这个问题谁可以帮助我?
我感谢这里的每一个帮助。谢谢
IMO 这是一个非常有效的算法,可以生成您所要求的内容。
这是我在 and 中使用的算法的变体,经过优化以执行最小分配。
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++;
}
}
}
示例用法:
bool test = "12334".GenerateWords().Contains("hello");
foreach (var word in "123454".GenerateWords())
{
// Do something with word
}
我正在尝试解密一个单词,其中的字母已被随机替换为其他字母(但不是将 2 个不同的字母替换为同一个字母)。
目标:
我正在搜索一个长度为 letter-pattern 的词。
我知道的:
该模式本身意味着如果搜索 "guests" 我知道“123454”,它显示了这个词中唯一字母的位置。我肯定知道它是一个正确书写的英文单词。
软件端:
我创建了一个 DataGridView
,其中 headers 以模式命名。我想用所有字母 a-z
.
Column
(模式)
我试过的:
我从最后开始 => 我已经成功实现了 spell-checker。所以最后我考虑只浏览这些列并检查每个结果以找到实际的单词。
从我看到的起点到目前为止我已经写了这个:
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
.
现在我需要在保持相同模式的同时循环字母。
这一步感觉比前面的更复杂。我想,在继续让我大吃一惊之前,我要看看 Whosebug 上是否有一些天才可以提供更简单的方法(也许是 LINQ 的一些快捷方式)。
所以,请问有没有人在想 "easy doin" 这个问题谁可以帮助我? 我感谢这里的每一个帮助。谢谢
IMO 这是一个非常有效的算法,可以生成您所要求的内容。
这是我在
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++;
}
}
}
示例用法:
bool test = "12334".GenerateWords().Contains("hello");
foreach (var word in "123454".GenerateWords())
{
// Do something with word
}