Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#通过参考费希尔·耶茨洗牌机_C#_Algorithm_Pass By Reference_Shuffle - Fatal编程技术网

c#通过参考费希尔·耶茨洗牌机

c#通过参考费希尔·耶茨洗牌机,c#,algorithm,pass-by-reference,shuffle,C#,Algorithm,Pass By Reference,Shuffle,我试图使用Fisher-Yates算法来洗牌一堆元素。我无法通过引用传递堆栈。下面的代码给出了错误“迭代器不能有ref或out参数”。如何让算法作用于传入的实际堆栈 谢谢 代码如下 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public static class Doshuffle { publ

我试图使用Fisher-Yates算法来洗牌一堆元素。我无法通过引用传递堆栈。下面的代码给出了错误“迭代器不能有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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序1
{
公共静态类剂量
{
公共静态IEnumerable Shuffle(参考堆栈源)
{
随机rng=新随机();
T[]元素=source.ToArray();
source.Clear();
//注意i>0以避免最终无意义的迭代
对于(int i=elements.Length-1;i>0;i--)
{
//将元素“i”与随机较早的元素it(或其本身)交换
int swapIndex=rng.Next(i+1);
T tmp=元素[i];
元素[i]=元素[swapIndex];
元素[swapIndex]=tmp;
}
//惰性屈服(避免别名问题等)
foreach(元素中的T元素)
{
推送(元素);
收益-收益要素;
}
}
}
}

如何让算法作用于传递的实际堆栈 在哪

由于
Stack
是一种引用类型,您不需要在此处使用
ref
参数,并且您不会尝试重新分配引用本身

默认情况下,引用是按值传递的,但该值(引用)指向堆上的同一对象,换句话说,您有两个引用指向同一对象,这很好-所有操作都将在原始
堆栈
对象上执行

编辑:

根据您的评论,我建议您重新设计,不要修改原始的
堆栈
,这一点从一开始就很麻烦:

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;
    }
}
使用
Random
时也要小心-您可能希望将其传入。在这一点上,你可以使用而不是你自己的-这是更好的重用比重新发明

最终编辑:

看起来您只是想在适当的位置洗牌
堆栈
——请改用扩展方法:

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);
    }
}
如何让算法作用于传递的实际堆栈 在哪

由于
Stack
是一种引用类型,您不需要在此处使用
ref
参数,并且您不会尝试重新分配引用本身

默认情况下,引用是按值传递的,但该值(引用)指向堆上的同一对象,换句话说,您有两个引用指向同一对象,这很好-所有操作都将在原始
堆栈
对象上执行

编辑:

根据您的评论,我建议您重新设计,不要修改原始的
堆栈
,这一点从一开始就很麻烦:

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;
    }
}
使用
Random
时也要小心-您可能希望将其传入。在这一点上,你可以使用而不是你自己的-这是更好的重用比重新发明

最终编辑:

看起来您只是想在适当的位置洗牌
堆栈
——请改用扩展方法:

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);
    }
}

堆栈不需要像那样通过引用传递,因为引用类型(如
stack
)已经通过引用传递了。在引用参数上使用
ref
out
修饰符的唯一原因是,如果您想实际修改引用本身(例如创建一个新的
堆栈
,并将其作为一种可选的返回方法分配给参数——与C中的双指针相同).

堆栈不需要像那样通过引用传递,因为引用类型(如
堆栈
)已经通过引用传递。在引用参数上使用
ref
out
修饰符的唯一原因是,如果您想实际修改引用本身(例如创建一个新的
堆栈
,并将其作为一种可选的返回方法分配给参数——与C中的双指针相同)。

因为堆栈是一个类,我认为在这种情况下不需要ref关键字。

如果没有它,它应该可以工作。

因为Stack是一个类,我认为在这种情况下不需要ref关键字。

没有它应该可以用。

使用Jon的:你不需要
ref
,但我几乎要说把它留在里面。返回一个
IEnumerable
和修改传入集合的组合是相当可疑的。使用Jon's:您不需要
ref
,但我几乎要说的是保留它。返回
IEnumerable
和修改传入集合的组合非常可疑。那么为什么下面的代码以原始形式显示堆栈<代码>洗牌。洗牌(游戏组)
foreach(gameDeck中的var项){System.Console.WriteLine(item.cardName);}
@FrankAMan:我想你误解了迭代器在C#中是如何阻止/产生的:结果是惰性地评估的——除非你迭代
DoShuffle()的结果
或执行类似于
Doshuffle.Shuffle(gameDeck).ToList()的操作。
您的迭代器块甚至无法启动,并且您的gameDeck尚未清除。感谢您的帮助。我根据乔恩·斯基特的帖子改编了我的版本。我只需要一些我可以调用
Doshuffle.Shuffle(游戏组)的东西
和gameDeck(这是一个堆栈)被洗牌。我希望修改原始堆栈,而不是返回每个元素。似乎在你的方法中,我必须使用foreach循环来让牌组洗牌。还有其他的方法吗?@FrankAMan:Updated-使用扩展方法谢谢,了解更多细节。这很好地工作,而且对于我所有的不同