Oje*_*jen 1 c# algorithm shuffle pass-by-reference
我试图使用Fisher-Yates算法来混淆一堆元素.我无法通过引用传入堆栈.下面的代码给出了错误"Iterators不能有ref或out参数".如何让算法对传入的实际堆栈起作用?
谢谢.
代码如下.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public static class Doshuffle
{
public static IEnumerable<T> Shuffle<T>(ref Stack<T> source)
{
Random rng = new Random();
T[] elements = source.ToArray();
source.Clear();
// Note i > 0 to avoid final pointless iteration
for (int i = elements.Length - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
T tmp = elements[i];
elements[i] = elements[swapIndex];
elements[swapIndex] = tmp;
}
// Lazily yield (avoiding aliasing issues etc)
foreach (T element in elements)
{
source.Push(element);
yield return element;
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
如何让算法对传入的实际堆栈起作用?
你没有需要ref,因为这里的参数Stack<T>是引用类型,你是不是要重新分配基准本身.
默认情况下,引用按值传递,但该值(引用)指向堆上的同一个对象,换句话说,您有两个引用指向同一个对象,这很好 - 所有操作都将在原始Stack<T>对象上执行.
编辑:
根据您的评论,我建议您重新设计,不要修改原始Stack<T>的麻烦:
public static IEnumerable<T> Shuffle<T>(Stack<T> source)
{
Random rng = new Random();
T[] elements = source.ToArray();
// Note i > 0 to avoid final pointless iteration
for (int i = elements.Length - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
T tmp = elements[i];
elements[i] = elements[swapIndex];
elements[swapIndex] = tmp;
}
// Lazily yield (avoiding aliasing issues etc)
foreach (T element in elements)
{
yield return element;
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以像这样使用它:
foreach (var item in Doshuffle.Shuffle(gameDeck))
{
System.Console.WriteLine(item.cardName);
}
Run Code Online (Sandbox Code Playgroud)
另外要小心使用Random- 你可能想要传入它.此时你可以使用Jon Skeet的Shuffle实现而不是你自己的实现 - 重用比重新创建更好.
最终编辑:
看起来你只想把自己洗牌Stack<T>- 使用扩展方法代替:
public static void Shuffle<T>(this Stack<T> source)
{
Random rng = new Random();
T[] elements = source.ToArray();
source.Clear();
// Note i > 0 to avoid final pointless iteration
for (int i = elements.Length - 1; i > 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
int swapIndex = rng.Next(i + 1);
T tmp = elements[i];
elements[i] = elements[swapIndex];
elements[swapIndex] = tmp;
}
foreach (T element in elements)
{
source.Push(element);
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
gameStack.Shuffle();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |