I am using the Knuth-Fisher-Yates algorithm to display a shuffled array of string items on a windows form. I do not get any duplicates, which is what I was trying to achieve, however, it only spits out 12 of the 13 elements of the array. How can I get it to d开发者_Python百科isplay all 13 elements of the array? Here is my code:
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;
}
You don't access the first element. for (int i = stationOneParts.Length - 1; i >= 0; i--).
As you are showing the texts using the loop that swaps the items, you will not show the last item, because it's never swapped by itself.
Just show the last item after the loop:
labelBlueOne.Text += stationOneParts[0] + "\n";
Alternatively, you can display all the items outside the loop that shuffles them:
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);
Change your loop condition to i >= 0
.
Simpliest approach :
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);
Since you mention C# 4.0, why not write is C#-ish?
using System.Linq;
// ...
var stationOneParts = new [] { "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" };
Random rand = new Random();
stationOneParts = stationOneParts
.Distinct() // see subject: '... without duplicates'
.Select(i => new { i, key=rand.Next() })
.OrderBy(p => p.key)
.Select(p => p.i)
.ToArray();
精彩评论