3

我正在尝试测试(与内存中的另一个值比较)字符串中所有可能的组合,但想知道最好的方法是什么。

我的输入字符串是0246,诀窍是每个数字都可以是 2 个选项之一,例如:

[0,1][2,3][4,5][6,7]

我希望能够翻阅所有可能的组合,这有点像破解保险箱,但这不是我的目的,我保证!

我正在考虑做一个foreach循环来切换每个选项,但我的循环会嵌套,我知道性能会受到影响,因为 Linq 就像新的黑色,可以用它来完成吗?

更新*

我希望结果按从低到高的顺序返回,因为我正在比较的原始字符串可能是 0001 但随机跳转没有意义。

我还想跟踪我必须生成多少次不同的变体,并记下它,因为它将在以后使用。

4

3 回答 3

7

你是这个意思吗:

var allCombinations = from a in new[] { "0", "1", }
                      from b in new[] { "2", "3", }
                      from c in new[] { "4", "5", }
                      from d in new[] { "6", "7", }
                      select a + b + c + d;

或者更花哨:

var allCombinations = from a in "01"
                      from b in "23"
                      from c in "45"
                      from d in "67"
                      select string.Concat(a, b, c, d);

在后一个(花式)版本abcdchar变量,string.Concat(a, b, c, d)也可以写成a.ToString() + b + c + d

于 2013-09-27T20:25:11.177 回答
2

这是一种适用于任意数量输入的方法(在将格式解析为 之后int[][]),使用Aggregateand Join

var data = new[]
{
    new[] { 0, 1 },
    new[] { 2, 3 },
    new[] { 4, 5 },
    new[] { 6, 7 },
};
var nums = data.Aggregate(new[] { "" }.AsEnumerable(),
        (agg, arr) => agg.Join(arr, x => 1, x => 1, (i, j) => i.ToString() + j));

输出:

0246 
0247 
0256 
0257 
0346 
0347 
0356 
0357 
1246 
1247 
1256 
1257 
1346 
1347 
1356 
1357 

它使用 LINQ,所以它可能不是有史以来最快的东西(对于我来说,这个数据仍然 < 1 毫秒),而且我如何使用Join固定连接值,所以它可能不是最好的东西,但是嘿 -有用。

我假设您实际上需要列出的所有值。如果您真正想要做的只是查看该值是否与看起来像有效密码的东西匹配,那么像Dmitry 的解决方案这样的正则表达式可能是要走的路。

于 2013-09-27T20:35:04.910 回答
1

要测试您记忆中的值,您不需要生成所有可能的值。生成完整的字符串并对其进行比较是完成这项工作的更糟糕的方法。

如果您想控制比较(计数操作)的过程,您不能使用任何内置方法(正则表达式或Linq)。您应该手动检查字符串中的所有字符并检查它们。

public bool Test(string input, string[] possibleValues)
{
    int operationsCount = 0;
    if (input.Length != possibleValues.Length)
    {
        return false;
    }

    for (int i = 0; i < input.Length; i++)
    {
        bool found = false;
        for (int j = 0; j < possibleValues[i].Length; j++)
        {
            operationsCount++;
            if (input[i] == possibleValues[i][j])
            {
                found = true;
                break;
            }
        }
        if (!found)
        {
            Console.WriteLine("Value does not satisfies the condition. Number of operations: " + operationsCount);
            return false;
        }
    }
    Console.WriteLine("Value satisfies the condition. Number of operations: " + operationsCount);
    return true;
}

Test("0247", new string[] { "01", "23", "45", "67" });

最短的方法是可以使用正则表达式来检查输入字符串是否满足条件。正则表达式是为将字符串与特定模式匹配而构建的。此解决方案的唯一问题是:您无法确定您进行了多少操作。

public bool Test(string input, string[] possibleValues)
{
    String pattern = GeneratePattern(possibleValues);
    bool result = Regex.IsMatch(input, pattern);
    if (!result)
        {
            Console.WriteLine("Value does not satisfies the condition.");
        }
    else
    {
        Console.WriteLine("Value satisfies the condition.");
    }
    return result;
}

private string GeneratePattern(string[] possibleValues)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("^");
    foreach (var possibleValue in possibleValues)
    {
        sb.Append("[");
        sb.Append(possibleValue);
        sb.Append("]");
    }
    sb.Append("$");
    return sb.ToString();
}
于 2013-09-27T20:26:46.387 回答