在c#中随机化泛型列表顺序的最佳方法是什么?我在一个列表中有一个有限的75个数字集,我想随机分配一个顺序,以便为彩票类型的应用程序绘制它们。
当前回答
public Deck(IEnumerable<Card> initialCards)
{
cards = new List<Card>(initialCards);
public void Shuffle()
}
{
List<Card> NewCards = new List<Card>();
while (cards.Count > 0)
{
int CardToMove = random.Next(cards.Count);
NewCards.Add(cards[CardToMove]);
cards.RemoveAt(CardToMove);
}
cards = NewCards;
}
public IEnumerable<string> GetCardNames()
{
string[] CardNames = new string[cards.Count];
for (int i = 0; i < cards.Count; i++)
CardNames[i] = cards[i].Name;
return CardNames;
}
Deck deck1;
Deck deck2;
Random random = new Random();
public Form1()
{
InitializeComponent();
ResetDeck(1);
ResetDeck(2);
RedrawDeck(1);
RedrawDeck(2);
}
private void ResetDeck(int deckNumber)
{
if (deckNumber == 1)
{
int numberOfCards = random.Next(1, 11);
deck1 = new Deck(new Card[] { });
for (int i = 0; i < numberOfCards; i++)
deck1.Add(new Card((Suits)random.Next(4),(Values)random.Next(1, 14)));
deck1.Sort();
}
else
deck2 = new Deck();
}
private void reset1_Click(object sender, EventArgs e) {
ResetDeck(1);
RedrawDeck(1);
}
private void shuffle1_Click(object sender, EventArgs e)
{
deck1.Shuffle();
RedrawDeck(1);
}
private void moveToDeck1_Click(object sender, EventArgs e)
{
if (listBox2.SelectedIndex >= 0)
if (deck2.Count > 0) {
deck1.Add(deck2.Deal(listBox2.SelectedIndex));
}
RedrawDeck(1);
RedrawDeck(2);
}
其他回答
我通常使用:
var list = new List<T> ();
fillList (list);
var randomizedList = new List<T> ();
var rnd = new Random ();
while (list.Count != 0)
{
var index = rnd.Next (0, list.Count);
randomizedList.Add (list [index]);
list.RemoveAt (index);
}
解决这类问题的一个非常简单的方法是在列表中使用一些随机的元素交换。
在伪代码中是这样的:
do
r1 = randomPositionInList()
r2 = randomPositionInList()
swap elements at index r1 and index r2
for a certain number of times
如果你不介意使用两个list,那么这可能是最简单的方法,但可能不是最有效或最不可预测的方法:
List<int> xList = new List<int>() { 1, 2, 3, 4, 5 };
List<int> deck = new List<int>();
foreach (int xInt in xList)
deck.Insert(random.Next(0, deck.Count + 1), xInt);
实现:
public static class ListExtensions
{
public static void Shuffle<T>(this IList<T> list, Random random)
{
for (var i = list.Count - 1; i > 0; i--)
{
int indexToSwap = random.Next(i + 1);
(list[indexToSwap], list[i]) = (list[i], list[indexToSwap]);
}
}
}
例子:
var random = new Random();
var array = new [] { 1, 2, 3 };
array.Shuffle(random);
foreach (var item in array) {
Console.WriteLine(item);
}
.NET小提琴演示
我们可以为List使用扩展方法,并使用线程安全的随机生成器组合。我在NuGet上打包了一个改进的版本,并在GitHub上提供源代码。NuGet版本包含可选的密码强随机。
Pre -。NET 6.0版本:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
if (list == null) throw new ArgumentNullException(nameof(list));
int n = list.Count;
while (n > 1)
{
int k = ThreadSafeRandom.Instance.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
internal class ThreadSafeRandom
{
public static Random Instance => _local.Value;
private static readonly Random _global = new Random();
private static readonly ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
{
int seed;
lock (_global)
{
seed = _global.Next();
}
return new Random(seed);
});
}
在。net 6.0或更高版本上:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
ArgumentNullException.ThrowIfNull(list);
int n = list.Count;
while (n > 1)
{
int k = Random.Shared.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
通过NuGet安装库以获得更多功能。
推荐文章
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法
- 如何从字符串中删除新的行字符?
- 如何设置一个默认值与Html.TextBoxFor?
- 检查属性是否有属性