测试字符串中的所有可能性

时间:2013-09-27 20:15:17

标签: c# string linq c#-4.0

我正在尝试对字符串中的所有可能组合进行测试(与内存中的其他值进行比较),但想知道最佳方法是什么。

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

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

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

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

UPDATE *

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

我还想跟踪我有多少次生成不同的变体,并注意到它会在以后使用。

3 个答案:

答案 0 :(得分: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);

在后者(花哨)版本a中,bcdchar变量,string.Concat(a, b, c, d)也可以写a.ToString() + b + c + d

答案 1 :(得分:2)

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

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's solution这样的正则表达式可能就是这样。

答案 2 :(得分: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" });

最简单的方法是使用Regular expression来检查输入字符串是否满足条件。构建正则表达式以匹配特定模式的字符串。此解决方案中唯一的问题是:您无法确定所执行的操作数量。

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();
}