C# 使用Random类对二维阵列进行随机化

C# 使用Random类对二维阵列进行随机化,c#,arrays,random,C#,Arrays,Random,我正试图在2d数组中随机化一组预先确定的元素 using System; namespace array { public class tiles { static void Main(string[] args) { Random random = new Random(); int[,] tilearr = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } };

我正试图在2d数组中随机化一组预先确定的元素

using System;

namespace array
{
    public class tiles
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            int[,] tilearr = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } };

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Console.Write(tilearr[i, j] + " ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
}
我所追求的更像这样:

2 4 8  1 3 0
0 3 1  5 6 8 
6 7 5, 2 4 7

一个简单且切中要害的解决方案是,列出一个可用的数字列表,然后逐个位置,从列表中随机选择数字

像这样:

var numbers = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
for(int x = 0; x < 3; ++x) {
    for(int y = 0; y < 3; ++y) {
        // select a random number from the list ...
        int rand = random.Next(0, numbers.Count - 1);
        tilearr[x, y] = numbers[rand];
        // ... and remove it from the list
        numbers.RemoveAt(rand);
    }
}
var number=新列表{0,1,2,3,4,5,6,7,8};
对于(int x=0;x<3;++x){
对于(int y=0;y<3;++y){
//从列表中选择一个随机数。。。
int rand=random.Next(0,number.Count-1);
tilerar[x,y]=数字[rand];
//…并将其从列表中删除
数字。RemoveAt(兰特);
}
}
如用户在评论中所述,洗牌将实现您想要的效果。我推荐费舍尔·耶茨洗牌

public static void Shuffle<T>(Random random, T[,] array)
{
    int lengthRow = array.GetLength(1);

    for (int i = array.Length - 1; i > 0; i--)
    {
        int i0 = i / lengthRow;
        int i1 = i % lengthRow;

        int j = random.Next(i + 1);
        int j0 = j / lengthRow;
        int j1 = j % lengthRow;

        T temp = array[i0, i1];
        array[i0, i1] = array[j0, j1];
        array[j0, j1] = temp;
     }
}
publicstaticvoidshuffle(随机,T[,]数组)
{
int lengthow=array.GetLength(1);
对于(int i=array.Length-1;i>0;i--)
{
int i0=输入/输出;
int i1=1%的纵投;
int j=随机。下一个(i+1);
int j0=j/L;
int j1=j%Lengthow;
温度=阵列[i0,i1];
阵列[i0,i1]=阵列[j0,j1];
阵列[j0,j1]=温度;
}
}
我从中检索了这个实现

这应该像这样在代码中实现

using System;

namespace array
{
    public class tiles
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            int[,] tilearr = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 } };
            Shuffle<int>(random, tilearr);

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Console.Write(tilearr[i, j] + " ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
}
使用系统;
命名空间数组
{
公共级瓷砖
{
静态void Main(字符串[]参数)
{
随机=新随机();
int[,]tilerar={{0,1,2},{3,4,5},{6,7,8};
洗牌(随机,平铺);
对于(int i=0;i<3;i++)
{
对于(int j=0;j<3;j++)
{
Console.Write(tilerar[i,j]+“”);
}
Console.WriteLine();
}
Console.ReadLine();
}
}
}
确保将shuffle泛型函数放在类中


是我在dotnetfiddle.net上实现的一个示例。

一种随机化的方法是将2d数组展平,洗牌,然后根据原始维度重新创建。如果要使用Linq/扩展方法,可以执行以下操作

Random random = new Random();
int[,] tilearr = {{ 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }};

var result = tilearr.OfType<int>()
       .OrderBy(x=> random.Next())
       .ChunkBy(tilearr.GetLength(1))
       .To2DArray();

Random Random=new Random();
int[,]tilerar={{0,1,2},{3,4,5},{6,7,8};
var result=tilerar.OfType()
.OrderBy(x=>random.Next())
.ChunkBy(tilerar.GetLength(1))
.To2DArray();
其中ChunkBy和To2DArray定义为

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize) 
    {
        return source
            .Select((x, i) => new { Index = i, Value = x })
            .GroupBy(x => x.Index / chunkSize)
            .Select(x => x.Select(v => v.Value));
    }

    public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
    {
        var data = source
            .Select(x => x.ToArray())
            .ToArray();

        var res = new T[data.Length, data.Max(x => x.Length)];
        for (var i = 0; i < data.Length; ++i)
        {
            for (var j = 0; j < data[i].Length; ++j)
            {
                res[i,j] = data[i][j];
            }
        }

        return res;
    }
}
公共静态类扩展
{
公共静态IEnumerable ChunkBy(此IEnumerable源,int chunkSize)
{
返回源
.Select((x,i)=>new{Index=i,Value=x})
.GroupBy(x=>x.Index/chunkSize)
.Select(x=>x.Select(v=>v.Value));
}
公共静态T[,]到2darray(此IEnumerable源)
{
var数据=来源
.Select(x=>x.ToArray())
.ToArray();
var res=新的T[data.Length,data.Max(x=>x.Length)];
对于(变量i=0;i

如果从头开始生成数组,则将一维数组随机化,然后将其加载到二维数组中会更容易

static int[,] GenerateArray(int size)
{
    Random r = new Random();   
    var arr = new int[size, size];
    var values = Enumerable.Range(0, size * size).OrderBy(x => r.Next()).ToArray();

    for (int i = 0; i < size; i++)
        for (int j = 0; j < size; j++)
            arr[i, j] = values[i * size + j];

    return arr;
}
static int[,]generatarray(int size)
{
随机r=新随机();
var arr=新整数[大小,大小];
var values=Enumerable.Range(0,size*size).OrderBy(x=>r.Next()).ToArray();
对于(int i=0;i
替代值是否要随机化数组但不重复?如果不希望重复,则要将一组值(或项)按随机顺序排列。这就是所谓的洗牌,这里有成千上万的帖子。xanatos给出了一个很棒的答案:一个非常简单的洗牌算法是这样的:“指向”最后一个元素。现在随机选择前面的元素。交换这两个元素。然后“指向”倒数第二个元素,随机选择前面的一个元素并切换这两个元素。依此类推,直到你“指向”第一个元素。嗯,我知道名称数组不存在吗?我做错什么了吗?如果你能复制准确的错误代码或进行回溯,这将有助于我理解你的意思。在shuffle函数
publicstaticvoidshuffle(Random,T[,]数组)中
它说名称数组不存在。我添加了一个实现示例,请尝试该链接中的代码,以确保它不是一个简单的错误。这只是virtual studio创建函数时的一个简单错误,由于某些原因,它不正确,我处于自动驾驶状态,只是没有检查它是否存在故障
static int[,] GenerateArray(int size)
{
    Random r = new Random();   
    var arr = new int[size, size];
    var values = Enumerable.Range(0, size * size).OrderBy(x => r.Next()).ToArray();

    for (int i = 0; i < size; i++)
        for (int j = 0; j < size; j++)
            arr[i, j] = values[i * size + j];

    return arr;
}