首页 新闻 会员 周边 捐助

一个看起来容易实现但是一写就头痛的一段小代码

0
悬赏园豆:20 [已解决问题] 解决于 2015-12-30 12:18

设想 现在有一个密码锁 假如现在有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循环。不知道怎样写代码实现对任意长度密码进行遍历。(密码一共有多少种组合很容易算出来,就是每一维数组的长度相乘可以得到,但是怎么再不确定位数的情况下全部遍历出来就感觉很麻烦)希望大神解答!

无线电静默的主页 无线电静默 | 初学一级 | 园豆:28
提问于:2015-12-30 11:32
< >
分享
最佳答案
2

正如一楼所说,需要笛卡尔积。之前写着玩的一段代码,希望对你有帮助

 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 }

运行结果:

收获园豆:20
zucker1988 | 小虾三级 |园豆:586 | 2015-12-30 11:54

完美解决 谢谢  不过我照着视频学 C#  算法什么的 对于目前的我来说还比较高端!

无线电静默 | 园豆:28 (初学一级) | 2015-12-30 12:17

知道笛卡尔积 也学过线性代数   但是这算法看懂还用了不短的时间     : (

_Arnold | 园豆:635 (小虾三级) | 2015-12-30 15:51
其他回答(3)
2

去研究一下笛卡尔积算法。相信会对你有所帮助的。没有那么麻烦。

大楚打码人 | 园豆:4313 (老鸟四级) | 2015-12-30 11:38

谢谢提醒~!

支持(0) 反对(0) 无线电静默 | 园豆:28 (初学一级) | 2015-12-30 12:17
0

楼上说的没错,去看看笛卡尔积算法

搁忆 | 园豆:612 (小虾三级) | 2015-12-30 12:08
0

楼主的意思是组成密码的字符集是已知的,且已知密码最大的可能长度,要穷举出所有可能的密码字符串,是这样的吗?

如果是这样的话,考虑到密码字符集不确定,最大长度不确定,楼主贴出来的代码既复杂,又没有通用性,我可以给一个很简单的实现,也用不着笛卡尔集这种貌似高深的概念了。

脚本王子 | 园豆:779 (小虾三级) | 2015-12-30 12:25

真的么  我的要求就是  字符集是确定的  但是密码位数 不确定  穷举所有的可能  实际上我要做的并不是,能够穷举 5位的密码 也能穷举50位的密码 能实现么?

 

支持(0) 反对(0) 无线电静默 | 园豆:28 (初学一级) | 2016-01-07 22:39

是的,很容易实现,楼主不妨新发一个博问,我为你解答。

支持(0) 反对(0) 脚本王子 | 园豆:779 (小虾三级) | 2016-01-08 21:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册