C# 不带重复项的洗牌字符串数组

C# 不带重复项的洗牌字符串数组,c#,.net-4.0,C#,.net 4.0,我使用Knuth Fisher-Yates算法在windows窗体上显示字符串项的无序数组。我没有得到任何重复,这是我试图实现的,但是,它只吐出数组13个元素中的12个。如何让它显示阵列的所有13个元素?这是我的密码: private void FormBlue1_Load(object sender, EventArgs e) { // set the forms borderstyle this.FormBorderStyle = FormBorderStyle.Fixed3D; // c

我使用Knuth Fisher-Yates算法在windows窗体上显示字符串项的无序数组。我没有得到任何重复,这是我试图实现的,但是,它只吐出数组13个元素中的12个。如何让它显示阵列的所有13个元素?这是我的密码:

private void FormBlue1_Load(object sender, EventArgs e)
{
// set the forms borderstyle
this.FormBorderStyle = FormBorderStyle.Fixed3D;

// create array of stationOneParts to display on form
string[] stationOneParts = new string[13];
stationOneParts[0] = "20-packing";
stationOneParts[1] = "5269-stempad";
stationOneParts[2] = "5112-freeze plug";
stationOneParts[3] = "2644-o'ring";
stationOneParts[4] = "5347-stem";
stationOneParts[5] = "4350-top packing";
stationOneParts[6] = "5084-3n1 body";
stationOneParts[7] = "4472-packing washer";
stationOneParts[8] = "3744-vr valve o'ring";
stationOneParts[9] = "2061-packing spring";
stationOneParts[10] = "2037-packing nut";
stationOneParts[11] = "2015-latch ring";
stationOneParts[12] = "stem assembly";

Random parts = new Random();

// loop through stationOneParts using a Swap method to shuffle
labelBlueOne.Text = "\n";
for (int i = stationOneParts.Length - 1; i > 0; i--)
{
int j = parts.Next(i + 1);
Swap(ref stationOneParts[i], ref stationOneParts[j]);

// display in a random order
labelBlueOne.Text += stationOneParts[i] + "\n";
}
}

private void Swap(ref string firstElement, ref string secondElement)
{
string temp = firstElement;
firstElement = secondElement;
secondElement = temp;
}

您不能访问第一个元素。
对于(inti=stationneparts.Length-1;i>=0;i--),不访问第一个元素。
对于(inti=stationOneParts.Length-1;i>=0;i--)。

将循环条件更改为
i>=0
将循环条件更改为
i>=0
当使用交换项的循环显示文本时,不会显示最后一个项,因为它永远不会自动交换

仅显示循环后的最后一项:

labelBlueOne.Text += stationOneParts[0] + "\n";
或者,您可以显示循环外部的所有项,这些项将被洗牌:

for (int i = stationOneParts.Length - 1; i > 0; i--) {
  Swap(ref stationOneParts[i], ref stationOneParts[parts.Next(i + 1)]);
}
labelBlueOne.Text = "\n" + String.Join("\n", stationOneParts);

当您使用交换项目的循环来显示文本时,您将不会显示最后一个项目,因为它本身从未交换过

仅显示循环后的最后一项:

labelBlueOne.Text += stationOneParts[0] + "\n";
或者,您可以显示循环外部的所有项,这些项将被洗牌:

for (int i = stationOneParts.Length - 1; i > 0; i--) {
  Swap(ref stationOneParts[i], ref stationOneParts[parts.Next(i + 1)]);
}
labelBlueOne.Text = "\n" + String.Join("\n", stationOneParts);
最简单的方法:

        Random rnd = new Random();
        var stationOneParts = new List<string>{
        "20-packing",
        "5269-stempad",
        "5112-freeze plug",
        "2644-o'ring",
        "5347-stem",
        "4350-top packing",
        "5084-3n1 body",
        "4472-packing washer",
        "3744-vr valve o'ring",
        "2061-packing spring",
        "2037-packing nut",
        "2015-latch ring",
        "stem assembly"}.OrderBy(s => rnd.Next());

        labelBlueOne.Text = string.Join(Environment.NewLine, stationOneParts);
Random rnd=new Random();
var stationOneParts=新列表{
“20包装”,
“5269斯坦帕德”,
“5112冻结塞”,
“2644-o'ring”,
“5347茎”,
“4350顶部包装”,
“5084-3n1阀体”,
“4472填料垫圈”,
“3744 vr阀o形圈”,
“2061填料弹簧”,
“2037填料螺母”,
“2015年锁环”,
“stem assembly”}.OrderBy(s=>rnd.Next());
labelBlueOne.Text=string.Join(Environment.NewLine,stationOneParts);
最简单的方法:

        Random rnd = new Random();
        var stationOneParts = new List<string>{
        "20-packing",
        "5269-stempad",
        "5112-freeze plug",
        "2644-o'ring",
        "5347-stem",
        "4350-top packing",
        "5084-3n1 body",
        "4472-packing washer",
        "3744-vr valve o'ring",
        "2061-packing spring",
        "2037-packing nut",
        "2015-latch ring",
        "stem assembly"}.OrderBy(s => rnd.Next());

        labelBlueOne.Text = string.Join(Environment.NewLine, stationOneParts);
Random rnd=new Random();
var stationOneParts=新列表{
“20包装”,
“5269斯坦帕德”,
“5112冻结塞”,
“2644-o'ring”,
“5347茎”,
“4350顶部包装”,
“5084-3n1阀体”,
“4472填料垫圈”,
“3744 vr阀o形圈”,
“2061填料弹簧”,
“2037填料螺母”,
“2015年锁环”,
“stem assembly”}.OrderBy(s=>rnd.Next());
labelBlueOne.Text=string.Join(Environment.NewLine,stationOneParts);
既然你提到了C#4.0,为什么不写C#ish呢

既然你提到了C#4.0,为什么不写它呢


这是随机的,但不能保证在可能的排序上给出均匀的分布。@递归:偏差的实际来源是RNG只有2^32=4 x 10^9个可能的种子,但有13个!=6 x 10^9 13个元素的可能顺序。因此,有20亿种可能的最终配置从未生成。如果这是一个问题,那么你需要一个更强大的随机性来源。(此外:默认的RNG种子是当前时间,这会引入额外的偏差,因为代码更有可能在工作时间运行。)@Guffa,@recursive:您的担心是对的,但在这种情况下,这不是问题。这里给出的代码是正确的,对其他问题进行了模化。当您执行类似这样的“OrderBy”时,排序代码会为每个项目获取一次排序键,缓存该键,并且不会重新计算该键。毕竟,密钥计算可能很昂贵!您正在考虑的问题是在比较器中使用随机性进行非基于键的比较排序。比较排序需要有一个由比较器施加的一致的总排序。@Guffa,@recursive:也就是说,您实际批评的算法是这样的:“myList.sort((x,y)=>random.Next(-1,2));”--这真的是大错特错。在每个比较对上都会进行新的比较,可能会有n个logn甚至n^2个比较,排序算法可能要求比较器保持一致。但是在Steve给出的算法中,他生成了n个排序键,仅此而已;我们不会在每次需要进行比较时都重新生成键。@Eric Lippert-在这种情况下,order by确实引入了偏差,因为它是一种稳定排序,如果任何键恰好相同,它将保留原始顺序。也就是说,在保持原始顺序方面存在一种罕见的偏差。这是随机的,但不能保证在可能的顺序上给出均匀分布。@递归:偏差的实际来源是RNG只有2^32=4 x 10^9个可能的种子,但有13个!=6 x 10^9 13个元素的可能顺序。因此,有20亿种可能的最终配置从未生成。如果这是一个问题,那么你需要一个更强大的随机性来源。(此外:默认的RNG种子是当前时间,这会引入额外的偏差,因为代码更有可能在工作时间运行。)@Guffa,@recursive:您的担心是对的,但在这种情况下,这不是问题。这里给出的代码是正确的,对其他问题进行了模化。当您执行类似这样的“OrderBy”时,排序代码会为每个项目获取一次排序键,缓存该键,并且不会重新计算该键。毕竟,密钥计算可能很昂贵!您正在考虑的问题是在比较器中使用随机性进行非基于键的比较排序。比较排序需要有一个由比较器施加的一致的总排序。@Guffa,@recursive:也就是说,您实际批评的算法是这样的:“myList.sort((x,y)=>random.Next(-1,2));”--这真的是大错特错。在每个比较对上都会进行新的比较,可能会有n个logn甚至n^2个比较,排序算法可能要求比较器保持一致。但是在Steve给出的算法中,他生成了n个排序键,仅此而已;我们不会在每次需要进行比较时重新生成键。@Eric Lippert-在这种情况下,顺序是