Random random = new Random();
/// <summary>
/// 随机打乱一个数组
/// </summary>
/// <param name="arr"></param>
public void Shuffle(Array arr)
{
    if (arr == null) return;
    for(int i = 0; i < arr.Length; i++)
    {
        int j = random.Next(arr.Length - i);
        object value = arr.GetValue(arr.Length - i - 1);
        arr.SetValue(arr.GetValue(j), arr.Length - i - 1);
        arr.SetValue(value, j);
    }
}private void button1_Click(object sender, EventArgs e)
{
    List<char> numbers = new List<char>();
    foreach (char c in "0123456789") numbers.Add(c);
    List<string> result = new List<string>();
    int[] counters = { 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
    Shuffle(counters);    char[] lastChars = "      ".ToCharArray();
    for (int i = 0; i < counters.Length; i++)
    {
        char[] currChars = "      ".ToCharArray();
        List<char> temps = new List<char>(numbers);
        for (int j = lastChars.Length - 1; j >= lastChars.Length - counters[i]; j--)
        {
            if (j == lastChars.Length - counters[i]) // 如果是最后一位就把0给去掉
                temps.Remove('0');
            temps.Remove(lastChars[j]);
            int k = random.Next(temps.Count);
            currChars[j] = temps[k];
            temps.RemoveAt(k);
        }
        lastChars = currChars;
        result.Add(new string(currChars));
    }
    foreach (string s in result)
    {
        Console.WriteLine(s);
    }
    Console.WriteLine("---------");
}
4个4位数。4个3位数,6个2位数 这些数加起来正好40个数字
上面的只是从0-9随机抽取的
如果能从4个0-9(也是40个数字)中抽取
输出结果如
 375
1950
  71
 834
  98
1826
  61
7098
 302
  94
 207
  64
7645
  53
就是0-9均衡出现4次

解决方案 »

  1.   

    按我1楼的思路是这样实现:
    Random random = new Random();
    /// <summary>
    /// 随机打乱一个数组
    /// </summary>
    /// <param name="arr"></param>
    public void Shuffle(Array arr)
    {
        if (arr == null) return;
        for(int i = 0; i < arr.Length; i++)
        {
            int j = random.Next(arr.Length - i);
            object value = arr.GetValue(arr.Length - i - 1);
            arr.SetValue(arr.GetValue(j), arr.Length - i - 1);
            arr.SetValue(value, j);
        }
    }public bool TryAccept(int[] ACounter, char[] AChars)
    {
        int l = 0;
        for (int i = 0; i < ACounter.Length; i++)
        {
            if (AChars[l] == '0') return false; // 第一位不能为0
            List<char> numbers = new List<char>();
            for (int j = l; j < l + ACounter[i]; j++) // 如果横向是重复的
            {
                if (numbers.IndexOf(AChars[j]) >= 0) return false;
                numbers.Add(AChars[j]);
            }
            if (i > 0) // 纵向相邻是否重复
            {
                for (int j = 0; j < Math.Min(ACounter[i], ACounter[i - 1]); j++)
                {
                    if (AChars[l + ACounter[i] - j - 1] ==
                        AChars[l + ACounter[i] - ACounter[i - 1] - 1 - j]) return false;
                }
            }
            l += ACounter[i];
        }
        return true;
    }
      

  2.   

    连上6楼的代码执行:
    private void button1_Click(object sender, EventArgs e)
    {
        int[] counters = { 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
        Shuffle(counters);
        char[] chars = "0000111122223333444455556666777788889999".ToCharArray();
        char[] buffer = "    ".ToCharArray();
        Shuffle(chars);
        while (!TryAccept(counters, chars))
        {
            Shuffle(chars);
        }
        int l = 0;
        for (int i = 0; i < counters.Length; i++)
        {
            Console.WriteLine(
                string.Format("{0,4}", new string(chars, l, counters[i])));
            l += counters[i];
        }
        Console.WriteLine("----");
    }
      

  3.   

    [align=right]69
    710
    206
    9613
    4582
    149
    82
    5403
    43
    867
    52
    90
    17
    8357
    ---------
    560
    70
    138
    792
    604
    25
    5184
    86
    8239
    21
    79
    3749
    6534
    10
    [/align]
      

  4.   

    public bool TryAccept(int[] ACounter, char[] AChars)
    {
        int l = 0;
        for (int i = 0; i < ACounter.Length; i++)
        {
            if (AChars[l] == '0') return false; // 第一位不能为0
            List<char> numbers = new List<char>();
            for (int j = l; j < l + ACounter[i]; j++) // 如果横向是重复的
            {
                if (numbers.IndexOf(AChars[j]) >= 0) return false;
                numbers.Add(AChars[j]);
            }
            if (i > 0) // 纵向相邻是否重复
            {
                for (int j = 0; j < Math.Min(ACounter[i], ACounter[i - 1]); j++)
                {
                    if (AChars[l + ACounter[i] - j - 1] ==
                        AChars[l - 1 - j]) return false; // 这里修正一下,上一个数据的最后一个数字从“l - 1”开始
                }
            }
            l += ACounter[i];
        }
        return true;
    }
      

  5.   

    我试出重复的
        Random random = new Random();
        /// <summary>
        /// 随机打乱一个数组
        /// </summary>
        /// <param name="arr"></param>
        public void Shuffle(Array arr)
        {
            if (arr == null) return;
            for (int i = 0; i < arr.Length; i++)
            {
                int j = random.Next(arr.Length - i);
                object value = arr.GetValue(arr.Length - i - 1);
                arr.SetValue(arr.GetValue(j), arr.Length - i - 1);
                arr.SetValue(value, j);
            }
        }    public bool TryAccept(int[] ACounter, char[] AChars)
        {
            int l = 0;
            for (int i = 0; i < ACounter.Length; i++)
            {
                if (AChars[l] == '0') return false; // 第一位不能为0
                List<char> numbers = new List<char>();
                for (int j = l; j < l + ACounter[i]; j++) // 如果横向是重复的
                {
                    if (numbers.IndexOf(AChars[j]) >= 0) return false;
                    numbers.Add(AChars[j]);
                }
                if (i > 0) // 纵向相邻是否重复
                {
                    for (int j = 0; j < Math.Min(ACounter[i], ACounter[i - 1]); j++)
                    {
                        if (AChars[l + ACounter[i] - j - 1] ==
                            AChars[l + ACounter[i] - ACounter[i - 1] - 1 - j]) return false;
                    }
                }
                l += ACounter[i];
            }
            return true;
        }    protected void Button1_Click(object sender, EventArgs e)
        {
            int[] counters = { 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
            Shuffle(counters);
            char[] chars = "0000111122223333444455556666777788889999".ToCharArray();
            char[] buffer = "    ".ToCharArray();
            Shuffle(chars);
            while (!TryAccept(counters, chars))
            {
                Shuffle(chars);
            }
            int l = 0;
            for (int i = 0; i < counters.Length; i++)
            {
                Response.Write(
                    string.Format("{0,4}", new string(chars, l, counters[i])));
                l += counters[i];
                Response.Write("<br />");
            }
              }
      

  6.   

    已经帖了,再测试看看吧!
    其实主要是TryAccept()方法。
    楼主可以根据自己的需求修改TryAccept()
      

  7.   

    核心代码就是它了,判断生成的随机数组是否符合楼主的需求
    实际上我的注释够多了,基本一看就明白的加也白加。
    public bool TryAccept(int[] ACounter, char[] AChars)
    {
        int l = 0; // 就是每行在AChars中的起始位置
        for (int i = 0; i < ACounter.Length; i++)
        {
            if (AChars[l] == '0') return false; // 第一位不能为0
            List<char> numbers = new List<char>();
            for (int j = l; j < l + ACounter[i]; j++) // 如果横向是重复的
            {
                if (numbers.IndexOf(AChars[j]) >= 0) return false; // 判断是否一行中存在重复
                numbers.Add(AChars[j]);
            }
            if (i > 0) // 纵向相邻是否重复
            {
                for (int j = 0; j < Math.Min(ACounter[i], ACounter[i - 1]); j++) // 相邻的行只判断最短的长度
                {
                    if (AChars[l + ACounter[i] - j - 1] ==
                        AChars[l - 1 - j]) return false; // 同一位置重复
                }
            }
            l += ACounter[i]; // 起始位置后移
        }
        return true;
    }主要是思路:
    拿那个你贴出的测试数据看
    int[] counters = { 3, 2, 3, 3, 3, 2, 4, 2, 4, 2, 2, 4, 4, 2 };
    char[] chars = "5607013879260425518486823921793749653410".ToCharArray();counters表示每行的长度3, 2, 3, 3, 3, 2, 4, 2, 4, 2, 2, 4, 4, 2
    这样chars要看成560 70 138 792 604 25 5184 86 8239 21 79 3749 6534 10
    然后就要计算每行的起始位置,如第一行为0 第二行就是第一行的长度 第三行就是第一行和第二行的和....
    然后就是体力活,按楼主提供的规则做出判断
    规则是楼主制订的,应该更清楚才是
      

  8.   

    [align=right]560 
    70 
    138 
    792 
    604 
    25 
    5184 
    86 
    8239 
    21 
    79 
    3749 
    6534 
    10 [/align]
    上面不是560和70 “0”相邻就是一样了
    中间5184 和86 “8”相邻也一样了