【发布时间】:2026-01-02 11:50:01
【问题描述】:
我有二维数组。我想随机选择一个插槽,并继续这样做,直到我最终选择了所有插槽(所以当然最后一次选择没有随机性)之前不要两次选择同一个插槽。是否有一个众所周知的算法来做到这一点?我正在使用 C#,但显然这更多的是关于算法而不是任何特定平台。是的,“大书”在我的购买清单上 :)
【问题讨论】:
-
您正在寻找一组插槽中的random permutation。
我有二维数组。我想随机选择一个插槽,并继续这样做,直到我最终选择了所有插槽(所以当然最后一次选择没有随机性)之前不要两次选择同一个插槽。是否有一个众所周知的算法来做到这一点?我正在使用 C#,但显然这更多的是关于算法而不是任何特定平台。是的,“大书”在我的购买清单上 :)
【问题讨论】:
看看 Fisher-Yates shuffle。它旨在从集合中选择随机排列。
【讨论】:
使用前面提到的Fisher-Yates shuffle 算法(在 O(n) 时间内)
int X = 3; int Y = 4;
int[] array = new int[X * Y];
for (int i = 0; i < array.Length; i++) array[i] = i;
FisherYatesShuffle(array);
var randomSlots = array.Select((i,j) => new {x=array[j]%X , y=array[j]/X })
.ToArray();
public static void FisherYatesShuffle<T>(T[] array)
{
Random r = new Random();
for (int i = array.Length - 1; i > 0; i--)
{
int j = r.Next(0, i + 1);
T temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
【讨论】:
假设你的数组是这样的:
Random rand = new Random();
object[,] array = new object[width,height];
bool[,] chosen = new bool[width,height];
int i, j;
do
{
i = rand.Next(width);
j = rand.Next(height);
} while (chosen[i,j]);
chosen[i,j] = true;
object current = array[i,j];
这应该可以正常工作。
【讨论】:
!,如果选择设置为 true,则该索引无效。我已经回滚了代码。
我这样做是为了数字
list<int> PastList=new PastList<int>();
private void Choоse()
{
int i = Recurs();
PastList.Add(i);
}
private int Recurs()
{
int i;
i = rnd.Next(0, 99);
if (PastList.Contains(i))
{
i = Recurs();
}
return i;
}
【讨论】: