C#中如何对二维数组的行进行随机打乱操作
实现方案
C# 中的二维数组[,]是连续内存布局,无法直接交换行,我们可以通过打乱行索引再重构数组的方式实现行级打乱,推荐使用Fisher-Yates洗牌算法保证随机概率均等:
完整代码示例
using System; using System.Linq; public static class ArrayShuffler { // 泛型方法,支持任意类型二维数组的行打乱 public static void ShuffleRows<T>(this T[,] array) { if (array == null) throw new ArgumentNullException(nameof(array)); Random random = new Random(); int rowCount = array.GetLength(0); int colCount = array.GetLength(1); // 生成初始行索引数组 int[] rowIndices = Enumerable.Range(0, rowCount).ToArray(); // Fisher-Yates 洗牌算法打乱索引 for (int i = rowCount - 1; i > 0; i--) { int swapIndex = random.Next(i + 1); (rowIndices[i], rowIndices[swapIndex]) = (rowIndices[swapIndex], rowIndices[i]); } // 按打乱后的索引生成新数组 T[,] shuffled = new T[rowCount, colCount]; for (int newRow = 0; newRow < rowCount; newRow++) { int sourceRow = rowIndices[newRow]; for (int col = 0; col < colCount; col++) { shuffled[newRow, col] = array[sourceRow, col]; } } // 覆盖原数组(如果不需要修改原数组,直接返回shuffled即可) Buffer.BlockCopy(shuffled, 0, array, 0, Buffer.ByteLength(shuffled)); } // 调用示例 public static void Main() { int[,] array = new int[3, 3] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; Console.WriteLine("原数组:"); PrintArray(array); array.ShuffleRows(); Console.WriteLine("\n打乱行后:"); PrintArray(array); } private static void PrintArray(int[,] array) { for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) { Console.Write(array[i, j] + " "); } Console.WriteLine(); } } }
简化方案(适配锯齿数组)
如果你可以将二维数组替换为锯齿数组[][](数组的数组),实现会更简洁:
int[][] jaggedArray = new int[][] { new int[] {1,2,3}, new int[] {4,5,6}, new int[] {7,8,9} }; // 直接对顶层数组做随机排序即可完成行打乱 Random rnd = new Random(); jaggedArray = jaggedArray.OrderBy(_ => rnd.Next()).ToArray();
注意事项
- 高并发场景下不要将
Random声明为局部变量,避免短时间生成重复随机序列,建议将Random提升为类的静态成员 - 如果不需要修改原数组,可直接返回打乱后的新数组,省略
Buffer.BlockCopy步骤
内容的提问来源于stack exchange,提问作者Alif Maulana
相关产品推荐
相关产品推荐

