设想 现在有一个密码锁 假如现在有3位 那么我想取得所有的密码组合 就需要用三个for循环嵌套
for (int i = 0; i < s[0].Length; i++) { for (int j = 0; j < s[1].Length; j++) { for (int k = 0; k < s[2].Length; k++) { combination[i * j + k] = s[0][i] + s[1][j] + s[2][k]; Console.WriteLine(combination[i * j + k]); } } }
比如像这样,其中密码每一位可能出现的字符用一个数组保存起来 本示例代码中有3位 显然
形如s[3][];由于每一位出现可能的字符不完全一样,所以s[][]是一个交错数组(假设这个数组我一开始就定义好了)。现在已知这个密码有三位的情况下可以用上述代码遍历 ,不过假如不知道密码的位数 这个密码位数是动态的,换句话说,就是不确定在遍历的时候 要用到几个for循环。不知道怎样写代码实现对任意长度密码进行遍历。(密码一共有多少种组合很容易算出来,就是每一维数组的长度相乘可以得到,但是怎么再不确定位数的情况下全部遍历出来就感觉很麻烦)希望大神解答!
正如一楼所说,需要笛卡尔积。之前写着玩的一段代码,希望对你有帮助
1 public static class CartesianProduct 2 { 3 public static void Run<T>(IList<T[]> sourceList, Action<T[]> action) 4 { 5 var combinedSetLength = 1; 6 7 sourceList.ForEach(values => combinedSetLength *= values.Length); 8 9 for (var i = 0; i < combinedSetLength; i++) 10 { 11 var tempSet = new List<T>(sourceList.Count); 12 var tempIndex = 1; 13 14 foreach (var items in sourceList) 15 { 16 tempIndex *= items.Length; 17 tempSet.Add(items[(i / (combinedSetLength / tempIndex)) % items.Length]); 18 } 19 20 action(tempSet.ToArray()); 21 } 22 } 23 }
用法:
1 private static void Main(params string[] args) 2 { 3 var source = new List<int[]> 4 { 5 new[] { 1, 2, 3 }, 6 new[] { 4, 5, 6 }, 7 new[] { 7, 8, 9 } 8 }; 9 10 CartesianProduct.Run(source, result => 11 { 12 Console.WriteLine(string.Join(",", result)); 13 }); 14 15 Console.ReadKey(true); 16 }
运行结果:
完美解决 谢谢 不过我照着视频学 C# 算法什么的 对于目前的我来说还比较高端!
知道笛卡尔积 也学过线性代数 但是这算法看懂还用了不短的时间 : (
去研究一下笛卡尔积算法。相信会对你有所帮助的。没有那么麻烦。
谢谢提醒~!
楼上说的没错,去看看笛卡尔积算法
楼主的意思是组成密码的字符集是已知的,且已知密码最大的可能长度,要穷举出所有可能的密码字符串,是这样的吗?
如果是这样的话,考虑到密码字符集不确定,最大长度不确定,楼主贴出来的代码既复杂,又没有通用性,我可以给一个很简单的实现,也用不着笛卡尔集这种貌似高深的概念了。
真的么 我的要求就是 字符集是确定的 但是密码位数 不确定 穷举所有的可能 实际上我要做的并不是,能够穷举 5位的密码 也能穷举50位的密码 能实现么?
是的,很容易实现,楼主不妨新发一个博问,我为你解答。