【穷举】用c#实现一个数组(1,1,2,2,3,3,4,4)排列,每两个相同数字中间都间隔了这个数字个数

从题目上看,这个感觉好绕口。其实嘛应该是我表述有问题。

举例吧:

1,[],1

2,[],[]2

这样子,两个相同数字之间要有几个坑。

其实这个数组计算量不算太大。推理能力好的话,分分钟解决了。

在这里我想通过程序去实现的目的:

1、为了空想这个实现过程,思想斗争了一晚上没睡觉,那种穷举方法比较好。其实我都没写过穷举。(--真是想太多)

2、了解下穷举算法。(我也不知道我下面写的方法算不算穷举。哈哈)

首先我们得有一个思路。【穷举出所有可能出现的排列方式=>规则匹配符合要求的数组 =>输出】

第一步:穷举

我的第一个错误的实现方法,我也写出来不怕丢人(嘿嘿)。那是这样的:

既然有八个位置。那么不考虑重复的情况下。(即默认它都是不相同的)

我们先定义八个字符串。

 1 string[] strs = new string[8] { "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8" };
 2            string[] temp = new string[8];
 3            int x=0;
 4            for (int i = 0; i < strs.Length; i++)
 5            {
 6                temp[0] = strs[i];
 7                for (int i1 = 0; i1 < strs.Length; i1++)
 8                {
 9                    if (temp[0]!=strs[i1])
10                    {
11                        temp[1] = strs[i1];
12                        for (int i2 = 0; i2 < strs.Length; i2++)
13                        {
14                            if (temp[0] != strs[i2]&&temp[1]!=strs[i2])
15                            {
16                                temp[2] = strs[i2];
17                                for (int i3 = 0; i3 < strs.Length; i3++)
18                                {
19                                    if (temp[0] != strs[i3] && temp[1] != strs[i3]&&temp[2]!=strs[i3])
20                                    {
21                                        temp[3] = strs[i3];
22                                        for (int i4 = 0; i4 < strs.Length; i4++)
23                                        {
24                                            if (temp[0] != strs[i4] && temp[1] != strs[i4] && temp[2] != strs[i4]&&temp[3]!=strs[i4])
25                                            {
26                                                temp[4] = strs[i4];
27                                                for (int i5 = 0; i5 < strs.Length; i5++)
28                                                {
29                                                    if (temp[0] != strs[i5] && temp[1] != strs[i5] && temp[2] != strs[i5] && temp[3] != strs[i5]&&temp[4]!=strs[i5])
30                                                    {
31                                                        temp[5] = strs[i5];
32                                                        for (int i6 = 0; i6 < strs.Length; i6++)
33                                                        {
34                                                            if (temp[0] != strs[i6] && temp[1] != strs[i6] && temp[2] != strs[i6] && temp[3] != strs[i6] && temp[4] != strs[i6]&&temp[5]!=strs[i6])
35                                                            {
36                                                                temp[6] = strs[i6];
37                                                                for (int i7 = 0; i7 < strs.Length; i7++)
38                                                                {
39                                                                    if (temp[0] != strs[i7] && temp[1] != strs[i7] && temp[2] != strs[i7] && temp[3] != strs[i7] && temp[4] != strs[i7] && temp[5] != strs[i7]&&temp[6]!=strs[i7])
40                                                                    {
41                                                                          temp[7] = strs[i7];
42                                                                          x++;//作为统计穷举次数
43                                                                          
44                                                                    }
45 
46                                                                }
47                                                            }
48 
49                                                        }
50                                                    }
51 
52                                                }
53                                            }
54 
55                                        }
56                                    }
57 
58                                }
59                            }
60 
61                        }
62                    }
63                    
64                }
65            }
66            Console.WriteLine(x);
67            Console.ReadLine();
68         }

血的教训告诉我们8*7*6*5*4*3*2=40320
我尝试过,如果每个字符串数组如果要输出的话,大概需要10分钟左右。更不要说,遍历每个字符串数组然后匹配规则,输出了。这才4个数字的,此方法直接扑街(pu  gai)!

第二种方法。直接利用相同的数字去排除。然后穷举:

方法举例:假设第一种方法中的“x1”,“x2”是1那么在第二种方法中 x1,x3,x2 只算一个,在第一种方法中算至少两个。

这种方法直接将数组减少到

不多说直接上代码

穷举方法二

整整减少为原来的1/16.

第二步:规则匹配。在所有可能的数组中找出符合要求的数组

穷举完了,接下来就是规则匹配。

遍历数组。然后根据两个相同数在数组中的索引位置差的绝对值为该数值加1;

注意:要考虑到索引超出界限的问题!

 1  public static bool IsYes(string[] str)
 2        {
 3            bool isYON = false;
 4             List<string> intList =new List<string>();
 5            for (int i = 0; i < str.Length; i++)
 6            {
 7                try
 8                {
 9 
10                    if (str[i] == str[i + Convert.ToInt32(str[i]) + 1] || str[i] == str[i - Convert.ToInt32(str[i]) - 1])
11                    {
12                        intList.Add(str[i]);
13                        isYON = true;
14                    }
15                    else
16                    {
17                        return false;
18                    }
19                }
20                catch (Exception)
21                {
22 
23                    if (str[i] == str[Math.Abs(i - Convert.ToInt32(str[i]) - 1)]&&intList.Contains(str[i]))
24                    {
25                        isYON = true;
26                    }
27                    else
28                    {
29                        return false;
30                    }
31                }
32            }
33            return isYON;
34        }
规则匹配

这样。

这篇文章并没有什么很高的技术含量。反而还比较考验思路的连贯性。

文笔不好,表述有不到位的地方,还请各位多多见谅。

本人对算法基本上是一无所知。如果有好的对算法的学习方法还请不啬赐教。将不胜感激!

如果有更好的实现的方法,或者改进的方法可以在下面评论指出或者发送到我的邮箱 paul_0715 at sina dot com

 

posted @ 2015-09-29 15:43  不再奢望  阅读(1165)  评论(0编辑  收藏  举报