我有一个二维的“卡片”数组,我需要在行和列中混洗这个数组。
我的数组是这样的:
private CardType[,] card =
{
{CardType.Basic, CardType.Basic2, CardType.Basic4 },
{CardType.Basic, CardType.Basic2, CardType.Basic30 },
{CardType.Basic, CardType.Basic10, CardType.Basic5 },
{CardType.Basic, CardType.Basic20, CardType.Basic30 },
};
我需要一种方法来在行和列中混洗卡阵列。
答案 0 :(得分:2)
使用Fisher-Yates算法:
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;
}
}
使用示例:
CardType[,] cards =
{
{ CardType.Basic, CardType.Basic2, CardType.Basic4 },
{ CardType.Basic, CardType.Basic2, CardType.Basic30 },
{ CardType.Basic, CardType.Basic10, CardType.Basic5 },
{ CardType.Basic, CardType.Basic20, CardType.Basic30 },
};
Random rnd = new Random();
Shuffle(rnd, cards);
请注意,您应该尝试重用rnd
,而不是重新创建它!
请注意array.Length
如何是数组的总Length
,X * Y,以及我们在i
中将其分割为“全局索引”i0
的方式, i1
(x
,y
)将模数除以“行”(lengthRow
)的长度。
答案 1 :(得分:1)
使用class Random
生成源行和dest行,source-col和dest-col。
交换这两个元素(如果不相同)
经常这样做。
答案 2 :(得分:1)
您可以使用标准shuffle来执行此操作。您只需要将单个索引转换为行/列值,如下所示:
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
public Shuffler()
{
_rng = new Random();
}
/// <summary>Creates the shuffler with a specific random number generator.</summary>
public Shuffler(Random rng)
{
_rng = rng;
}
/// <summary>Shuffles the specified array.</summary>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
/// <summary>Shuffles the specified 2D array.</summary>
public void Shuffle<T>(T[,] array)
{
int w = array.GetUpperBound(1)+1;
for (int n = array.Length; n > 1; )
{
int k = _rng.Next(n);
--n;
int dr = n/w;
int dc = n%w;
int sr = k/w;
int sc = k%w;
T temp = array[dr,dc];
array[dr,dc] = array[sr,sc];
array[sr,sc] = temp;
}
}
private readonly Random _rng;
}
您可以像这样使用它:
int[,] array = new int[5, 7];
int w = array.GetUpperBound(1)+1;
// Fill array with 0, 1, 2, ... , 5*7-1
for (int i = 0; i < array.Length; ++i)
{
int sr = i/w;
int sc = i%w;
array[sr, sc] = i;
}
var shuffler = new Shuffler();
shuffler.Shuffle(array);
Console.WriteLine(array[0,0]);