|
Your Shuffle-loop is incorrect; it starts at (n-1), where n=count. Meaning it will skip one!
Try something like below;
class Program
{
static void Main(string[] args)
{
RunQuestionTwo();
Console.ReadKey();
}
private static void RunQuestionTwo()
{
int arraySize;
int[] a;
Console.WriteLine("\nTask 2 \nPlease enter an integer to determine the size of the random array\n");
arraySize = Convert.ToInt16(Console.ReadLine());
a = new int[arraySize];
Console.WriteLine("\nThe array will now be displayed\n");
for (int i = 0; i < a.Length; i++)
{
a[i] = i + 1;
}
Shuffle(a);
}
public static void Shuffle(int[] a)
{
Random rndNumber = new Random();
int n = a.Length;
Console.WriteLine(string.Format("n = {0}", n));
for (int r = 0; r < n; r++)
{
int i = rndNumber.Next(1, n);
int temp = a[i];
a[i] = a[r];
a[r] = temp;
Console.WriteLine(a[r]);
}
}
} You'd also like to verify the users' input and prevent the app from blowing up on 'unexpected' input. I made the methods static, since that's preferred for methods that don't change (local object) state.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Thanks very much! It worked Also thanks to all others who helped
|
|
|
|
|
Try:
public void Shuffle(int[] a)
{
Random rndNumber = new Random();
int n = a.Length - 1;
while (n > -1)
{
int i = rndNumber.Next(0, n);
int temp = a[i];
a[i] = a[n];
a[n] = temp;
Console.WriteLine(a[n]);
n--;
}
} Test in some method:
int[] a = new int[5] { 1, 2, 3, 4, 5 };
for (int i = 0; i < 10; i++)
{
Shuffle(a);
Console.WriteLine();
} I'm not sure to what degree your shuffle method may provide "randomness," but, many folks question the inherent randomness of the .NET Random function itself. I suspect your shuffle is fine for general purpose use.
For a really advanced solution to this using Linq, with an interesting discussion of bringing GUID's into play to increase randomness: [^].
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
modified 16-Jan-14 10:33am.
|
|
|
|
|
I think that article is a bit wrong:
Quote: Every number will be the first in the sequence based on the supplied seed. If you call it twice with the same seed (i.e. within one tick) you will get the same number.
Random.Next() should return the next number in the pseudo-random sequence every time is called. You cannot 'call it with the same seed' (you have to creata a new instance of the Random class and it is usually done only by mistake).
Moreover, I don't buy the GUID argument as a general improvement because, while the Random.Next() provide you a pseudo-random sequence following a uniform distribution, I don't know the distribution System.Guid.newGuid() follows.
Veni, vidi, vici.
|
|
|
|
|
Just to add to what Bill and Eddy say, you should not declare the Random instance within the Shuffle method: it is initialized from the system clock when it is created, so if you call Shuffle twice in quick sucession, you could get the same random sequence.
Instead, declare it as a private class level variable and reuse the same instance each time Shuffle is called:
private static Random rndNumber = new Random();
public static void Shuffle(int[] a)
{
int n = a.Length;
...
There is another detail: did you notice that the first element is never shuffled? That's because your Random.Next call can't return zero...
BTW: Length is a property of an array - you don't need to treat it as a method! (And the compiler will complain if you do)
If you don't mind my saying, that isn't quite the way I'd do it. I don't know how much you know yet, but I wouldn't do an in-place shuffle. I'd would arrange that the Shuffle method returned a new set of values rather than reorganising the original, and I'd probably make it generic. Heck, does this make any sense to you?
int[] a = new int[arraySize];
for (int i = 0; i < a.Length; i++)
{
a[i] = i + 1;
}
int[] b = Shuffle(a).ToArray();
Console.WriteLine("\nThe array will now be displayed\n");
foreach (int i in b)
{
Console.WriteLine(i);
}
}
private static Random rndNumber = new Random();
public static IEnumerable<T> Shuffle<T>(IEnumerable<T> a)
{
int values = a.Count();
List<T> output = new List<T>(values);
List<T> input = a.ToList();
for (int index = 0; index < values; index++)
{
int i = rndNumber.Next(0, input.Count());
output.Add(input[i]);
input.RemoveAt(i);
}
return output;
}
Never underestimate the power of stupid things in large numbers
--- Serious Sam
|
|
|
|
|
Really satisfying to see some back-and-forth here, and a variety of solutions !OriginalGriff wrote: your Random.Next call can't return zero I beg to differ: the 'Next method of the Random Class can, indeed return it's first minValue argument:
"minValue Type: System.Int32 The inclusive lower bound of the random number returned." Oh ... wait ... I see ... ... my bad ... you are referring only to Eddie's code.
I agree with you that initializing the Array in advance is a waste of time. If I were going to "shuffle," I'd probably use the technique shown in the article I cited.OriginalGriff wrote: does this make any sense to you? Everything you say makes sense to me ... dammit
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
I meant the OPs original code, but yes, Eddies code also has a minValue of one.
I agree, this was a better format for questions because it encouraged discussion and improvements, which I don't feel QA does: it seems to "compartmentalise" answers so there is less cross fertilisation between answers.
Never underestimate the power of stupid things in large numbers
--- Serious Sam
|
|
|
|
|
Two more candidates for the beauty contest:
Candidate One:
private Random newRandom = new Random();
private List<int> MakeShuffledList1(int nItems)
{
return Enumerable.Range(1, nItems).ToList().OrderBy(item => newRandom.Next()).ToList();
}
List<int> newList = MakeShuffledList1(10);
Candidate Two:
private Random newRandom = new Random();
private List<int> MakeShuffledList2(int nItems)
{
List<int> shuffleList = Enumerable.Range(1, nItems).ToList();
List<int> resultList = new List<int>();
int currentValue;
while (shuffleList.Count > 0)
{
currentValue = shuffleList[newRandom.Next(0, shuffleList.Count - 1)];
resultList.Add(currentValue);
shuffleList.Remove(currentValue);
}
return resultList;
} This follows the usual beauty pageant drill: when Miss/Mr. Whatever is crowned, you know he/she will not be in the next selection category.
Test:
List<List<int>> bunchOLists = new List<List<int>>();
for (int i = 0; i < 10; i++)
{
bunchOLists.Add(MakeShuffledList1(5));
bunchOLists.Add(MakeShuffledList2(5));
}
bool IsDuplicate = false;
List<int> currentList;
for (int i = 0; i < bunchOLists.Count - 1; i++)
{
currentList = bunchOLists[i];
for (int j = 0; j < bunchOLists.Count - 1; j++)
{
if(i != j)
{
IsDuplicate = currentList.SequenceEqual(bunchOLists[j]);
}
}
}
Console.WriteLine("all List<int> are unique: " + (! IsDuplicate).ToString());
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
modified 17-Jan-14 2:13am.
|
|
|
|
|
Message Closed
modified 17-Jan-14 4:52am.
|
|
|
|
|
Actually, it looks to me he is implementing the right algorithm.
Veni, vidi, vici.
|
|
|
|
|
I am a little confused what to put in Q/A and what to put in discussion. Can somebody explain what kind of query is to be put to Q/A and Discussion?
|
|
|
|
|
|
Years ago there was more of a difference than there is now, with the language Forums, like this one, often a place where broad general issues in programming with a given language were discussed at length, and QA more of a place for specific technical problems, and help-seeking.
But, in the last four years, imho, these categories have broken down in spite of requests, and specific proposals, from many people (including this insignificant person), to do something to maintain the original purpose of having two kinds of forums.
Given the state of CodeProject now, I'd say it hardly matters where you post.
Depending on which way the wind is blowing, however, and your "role" on CP, you may, or may not, get roasted if certain trigger-happy members are around.
Everything changes.
“But I don't want to go among mad people,” Alice remarked.
“Oh, you can't help that,” said the Cat: “we're all mad here. I'm mad. You're mad.”
“How do you know I'm mad?” said Alice.
“You must be," said the Cat, or you wouldn't have come here.” Lewis Carroll
|
|
|
|
|
thank you sir that answered my question.
|
|
|
|
|
An excellent summary Bill.
|
|
|
|
|
How to use SQL store procedure in LINQ in C#?
|
|
|
|
|
|
I'm developing a GUI(which needs to use Microsoft Office Obj Lib) using VS2013 C# on .Net Framework 3.5. I publish it and it runs fine on my PC (Windows 7, 64-bit OS) and get the .exe file and try running it on user PC(Windows XP, 32-bit OS).
The installation error keeps mentioning "The application requires ... assembly Microsoft.Vbe.Interop Version 15.0.0.0 to be installed in GAC first".
So I included Microsoft.Vbe.Interop in References (although I don't need it), build the program and publish it. The problem still persists.
Is there anyway I could publish an execution file which can be installed on the user PC straight away?
Thanks! I'm kinda lost and any help is much appreciated.
|
|
|
|
|
If your application has dependencies on other libraries, then you are going to have to create an installer, that will install all dependencies. I do not know of any other way of compiling dependencies into your exe file.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
|
IIRC we had a similar problem some years ago. We needed to tick a checkbox in the Office setup of the target machine to include Interop into the installation.
The good thing about pessimism is, that you are always either right or pleasently surprised.
|
|
|
|
|
Could you please elaborate more on this?
|
|
|
|
|
emma.sun.sts wrote: So I included Microsoft.Vbe.Interop in References
And where exactly did you reference it from?
|
|
|
|
|
From
C:\Program Files (x86)\Microsoft Visual Studio 13.0\Visual Studio Tools for Office\PIA\Office14
|
|
|
|
|
Excellent.
You might have to play round with the options a bit since they move. But basically you need to find an option that will cause the dll to be copied into your build (when you look at the build directory the file will be there.)
Under VS 2008 you do this by (I think)
- Right clicking on reference
- Click on properties
- Set "Copy local" to true.
|
|
|
|
|