Populate an array with random numbers

C

CES

I'm sorry because this should be simple. I'm trying to populate an array
with random numbers which is no problem however I can't figure out how to
check to make sure the number is not duplicated in the list???


int[] myArray = new int[5];
Random myRandomNumber = new Random();

for (int x = 0; x < myArray.Length; x++)
{
for(int i = 0; i <= x; i++){
bool myBool = false;
int temp =
myRandomNumber.Next(1, 5);

//
//Check against all populated
elements in array???
//

}
Console.WriteLine();

I've tried for 6 hours but I'm lost????
 
M

Morten Wennevik [C# MVP]

CES said:
I'm sorry because this should be simple. I'm trying to populate an array
with random numbers which is no problem however I can't figure out how to
check to make sure the number is not duplicated in the list???


int[] myArray = new int[5];
Random myRandomNumber = new Random();

for (int x = 0; x < myArray.Length; x++)
{
for(int i = 0; i <= x; i++){
bool myBool = false;
int temp =
myRandomNumber.Next(1, 5);

//
//Check against all populated
elements in array???
//

}
Console.WriteLine();

I've tried for 6 hours but I'm lost????

Hi,

You have a few options. You can use a brute force approach and either store
used numbers in a separate list or go through the existing one to make sure
the current number hasn't already been used. However, since you have an
array of five numbers that must be between 1 and 5 you can use a card dealing
approach.

Create a list of all the numbers you need and randomly move a number to the
final list.

int[] myArray = new int[5];
List<int> potList = new List<int> { 1, 2, 3, 4, 5 };
Random myRandom = new Random();
for (int i = 0; i < myArray.Length; i++)
{
myArray = potList[myRandom.Next(0, potList.Count)];
potList.Remove(myArray);
}

The trick is to remove used element from potList and change the random range
to the number of remaining elements.
 
C

CES

Peter I'm sure that your smarter then I am but I'm equally sure you know
exactly what I'm trying to do... as far as the code goes I'm sure there are
numerous problems with it... There is no such method in .NET called shuffle!
and if I could find a simple example of a shuffle implementation then it
would suffice for what I'm doing but it doesn't solve the issue how do you
iterate thru an array and make sure there are no duplicate values!

Thanks but after 10 hours of this I'M GOING TO BED!!!!!!!!!!!!!!!!
 
C

CES

Morton,
Thank you but I'm so new to .net I'm not sure what your doing in a few
places...

int[] myArray = new int[5];
// I’ve never seen List used before but it seems strait forward
it creates a list of a specific size or with elements of a specific value
//However could you please explain <int>, I’ve never seen this
<xxx> syntax???
// Is List<int> potList the same as List int potList??
List<int> potList = new List<int> { 1, 2, 3, 4, 5 };
Random myRandom = new Random();
for (int i = 0; i < myArray.Length; i++)
{
//This is where I'm really confused, I know that this is
where your randomizing the array but I’m not sure what it is your doing and
how it works???
myArray = potList[myRandom.Next(0, potList.Count)];
potList.Remove(myArray);
}
Console.WriteLine("-----");
for (int i = 0; i < myArray.Length; i++)
{
Console.WriteLine(myArray);
}
Console.Read();


Any Help on clarifying these issues would be greatly appreciated. Thank you
for your Help... and now I am going to bed. - CES


Morten Wennevik said:
CES said:
I'm sorry because this should be simple. I'm trying to populate an array
with random numbers which is no problem however I can't figure out how to
check to make sure the number is not duplicated in the list???


int[] myArray = new int[5];
Random myRandomNumber = new Random();

for (int x = 0; x < myArray.Length;
x++)
{
for(int i = 0; i <= x; i++){
bool myBool = false;
int temp =
myRandomNumber.Next(1, 5);

//
//Check against all populated
elements in array???
//

}
Console.WriteLine();

I've tried for 6 hours but I'm lost????

Hi,

You have a few options. You can use a brute force approach and either
store
used numbers in a separate list or go through the existing one to make
sure
the current number hasn't already been used. However, since you have an
array of five numbers that must be between 1 and 5 you can use a card
dealing
approach.

Create a list of all the numbers you need and randomly move a number to
the
final list.

int[] myArray = new int[5];
List<int> potList = new List<int> { 1, 2, 3, 4, 5 };
Random myRandom = new Random();
for (int i = 0; i < myArray.Length; i++)
{
myArray = potList[myRandom.Next(0, potList.Count)];
potList.Remove(myArray);
}

The trick is to remove used element from potList and change the random
range
to the number of remaining elements.
 
M

Michael C

CES said:
Morton,
Thank you but I'm so new to .net I'm not sure what your doing in a few
places...

int[] myArray = new int[5];
// I've never seen List used before but it seems strait forward
it creates a list of a specific size or with elements of a specific value
//However could you please explain <int>, I've never seen this
<xxx> syntax???
// Is List<int> potList the same as List int potList??

This is known as Generics (have a look in help or search google). I can give
you a simple explanation. Generics is a way to create an object based on
another type of object, for example, if we do

List<int> potList = new List<int> { 1, 2, 3);

we are creating a list based on an integer. Many of the calls to potList
will now accept (or return) integers. For example potList.Add will accept an
integer. We could also create a List object based on string, eg

List<string> myList = new List<string> { "A", "B", "C" };

now myList will have an Add method that requires a string.

A simple way to think of it is creating a List of integer in the first
example and a list of strings in the second example. The reason Morten used
a list is because it has a remove method and the Array does not.
List<int> potList = new List<int> { 1, 2, 3, 4, 5 };
Random myRandom = new Random();
for (int i = 0; i < myArray.Length; i++)
{
//This is where I'm really confused, I know that this is
where your randomizing the array but I'm not sure what it is your doing
and how it works???

He is getting a random element from potList, putting it into myArray and
then removing that element from the potList on the next line.
myArray = potList[myRandom.Next(0, potList.Count)];
potList.Remove(myArray);


Effectively he is starting with a deck of 5 cards (in potList) and dealing
them out to myArray in random order. As each "card" is dealt to myArray it
needs to be removed from potList so that it cannot be dealt again.

Michael
 
G

Gareth Erskine-Jones

I'm sorry because this should be simple. I'm trying to populate an array
with random numbers which is no problem however I can't figure out how to
check to make sure the number is not duplicated in the list???


int[] myArray = new int[5];
Random myRandomNumber = new Random();

for (int x = 0; x < myArray.Length; x++)
{
for(int i = 0; i <= x; i++){
bool myBool = false;
int temp =
myRandomNumber.Next(1, 5);

//
//Check against all populated
elements in array???
//

}
Console.WriteLine();

I've tried for 6 hours but I'm lost????

Will this do?

var ints = new List<int>();
var myRandomNumber = new Random();

int randomNumber = 0;
for (int x = 0; x < 10; x++)
{
while (ints.Contains(randomNumber))
{
randomNumber = myRandomNumber.Next(1, 20);
}

ints.Add(randomNumber);
}

int[] intArray = ints.ToArray();
 
G

Gareth Erskine-Jones

I'm sorry because this should be simple. I'm trying to populate an array
with random numbers which is no problem however I can't figure out how to
check to make sure the number is not duplicated in the list???


int[] myArray = new int[5];
Random myRandomNumber = new Random();

for (int x = 0; x < myArray.Length; x++)
{
for(int i = 0; i <= x; i++){
bool myBool = false;
int temp =
myRandomNumber.Next(1, 5);

//
//Check against all populated
elements in array???
//

}
Console.WriteLine();

I've tried for 6 hours but I'm lost????

Will this do?

var ints = new List<int>();
var myRandomNumber = new Random();

int randomNumber = 0;
for (int x = 0; x < 10; x++)
{
while (ints.Contains(randomNumber))
{
randomNumber = myRandomNumber.Next(1, 20);
}

ints.Add(randomNumber);
}

int[] intArray = ints.ToArray();

Sorry - an obvious bug there - your array will always start with 0.
Replace:

int randomNumber = 0;
with
randomNumber = myRandomNumber.Next(1, 20);

Depending on how big your array needs to be and the range of random
numbers that is acceptable this might be quite inefficient (the while
loop might be executed rather a lot). When I want to shuffle a list of
numbers I tend to use two lists - initialise the first one with the
numbers, and then randomly pick a number from that list, add it to the
second, and remove it from the first., Continue until the first list
is empty.
 
M

Michael C

Gareth Erskine-Jones said:
Will this do?

var ints = new List<int>();
var myRandomNumber = new Random();

int randomNumber = 0;
for (int x = 0; x < 10; x++)
{
while (ints.Contains(randomNumber))
{
randomNumber = myRandomNumber.Next(1, 20);
}

ints.Add(randomNumber);
}

int[] intArray = ints.ToArray();

That's not as efficient as this could be really.

Michael
 
P

Philipp Brune

Hi, i would suggest something like this :

First, you generate an array of all the numbers between 1..n,
then you randomly swap two elements a few times. So the array
has a random order and no duplicates.

In Code :

int[] array = new int[5];

for (int i = 0; i < array.Length; i++)
{
array = i + 1;
}

Random r = new Random();
for (int i = 0; i < array.Length; i++)
{
int target = r.Next(0, array.Length - 1);
// swap i and target
int temp = array;
array = array[target];
array[target] = temp;
}

Cheers,
Philipp
 
M

Markus Zeller

Hy,
another solution for your problem...

int[] result = GetRandom(Enumerable.Range(0, 100), 5, 0,
false).ToArray();

static IEnumerable<int> GetRandom(IEnumerable<int> source, int
count, int seed, bool allowDuplicates)
{
List<int> buffer = new List<int>(source);

Random random = seed < 0 ? new Random() : new Random(seed);

count = Math.Min(count, buffer.Count);

if (count <= 0)
yield break;

for (int i = 1; i <= count; i++)
{
int randomIndex = random.Next(buffer.Count);

yield return buffer[randomIndex];

if (!allowDuplicates)
buffer.RemoveAt(randomIndex);
}
}
 
C

CES

Michael,
I just wanted to thank you for you simple concise explanation of Morten's
code it was extremely helpful. It was much appreciated - CES

Michael C said:
CES said:
Morton,
Thank you but I'm so new to .net I'm not sure what your doing in a few
places...

int[] myArray = new int[5];
// I've never seen List used before but it seems strait
forward it creates a list of a specific size or with elements of a
specific value
//However could you please explain <int>, I've never seen this
<xxx> syntax???
// Is List<int> potList the same as List int potList??

This is known as Generics (have a look in help or search google). I can
give you a simple explanation. Generics is a way to create an object based
on another type of object, for example, if we do

List<int> potList = new List<int> { 1, 2, 3);

we are creating a list based on an integer. Many of the calls to potList
will now accept (or return) integers. For example potList.Add will accept
an integer. We could also create a List object based on string, eg

List<string> myList = new List<string> { "A", "B", "C" };

now myList will have an Add method that requires a string.

A simple way to think of it is creating a List of integer in the first
example and a list of strings in the second example. The reason Morten
used a list is because it has a remove method and the Array does not.
List<int> potList = new List<int> { 1, 2, 3, 4, 5 };
Random myRandom = new Random();
for (int i = 0; i < myArray.Length; i++)
{
//This is where I'm really confused, I know that this is
where your randomizing the array but I'm not sure what it is your doing
and how it works???

He is getting a random element from potList, putting it into myArray and
then removing that element from the potList on the next line.
myArray = potList[myRandom.Next(0, potList.Count)];
potList.Remove(myArray);


Effectively he is starting with a deck of 5 cards (in potList) and dealing
them out to myArray in random order. As each "card" is dealt to myArray it
needs to be removed from potList so that it cannot be dealt again.

Michael
 
T

Tim Roberts

Philipp Brune said:
Hi, i would suggest something like this :

First, you generate an array of all the numbers between 1..n,
then you randomly swap two elements a few times. So the array
has a random order and no duplicates.

In Code :

int[] array = new int[5];

for (int i = 0; i < array.Length; i++)
{
array = i + 1;
}

Random r = new Random();
for (int i = 0; i < array.Length; i++)
{
int target = r.Next(0, array.Length - 1);
// swap i and target
int temp = array;
array = array[target];
array[target] = temp;
}


I am glad somebody finally posted the reasonable way to do this.

I would point out that this is exactly how the STL "shuffle" method is
usually implemented.
 
M

Michael C

Tim Roberts said:
I am glad somebody finally posted the reasonable way to do this.

I think Morten's solution is faster, more efficient, simpler and produces a
better result. I really can't see why you'd use Philipp's method.

Michael
 
M

Michael C

Markus Zeller said:
Hy,
another solution for your problem...

int[] result = GetRandom(Enumerable.Range(0, 100), 5, 0,
false).ToArray();

static IEnumerable<int> GetRandom(IEnumerable<int> source, int
count, int seed, bool allowDuplicates)
{
List<int> buffer = new List<int>(source);

Random random = seed < 0 ? new Random() : new Random(seed);

count = Math.Min(count, buffer.Count);

if (count <= 0)
yield break;

for (int i = 1; i <= count; i++)
{
int randomIndex = random.Next(buffer.Count);

yield return buffer[randomIndex];

if (!allowDuplicates)
buffer.RemoveAt(randomIndex);
}
}

Nice solution but why not create it as an extension method?

Michael
 
M

Markus Zeller

Hy,

There is the solution as extension method and more generic ;)

public static IEnumerable<T> GetRandom<T>(this IEnumerable<T> source, int
count, int seed, bool allowDuplicates)
{
List<T> buffer = new List<T>(source);

Random random = seed < 0 ? new Random() : new Random(seed);

count = Math.Min(count, buffer.Count);

if (count <= 0)
yield break;

for (int i = 1; i <= count; i++)
{
int randomIndex = random.Next(buffer.Count);

yield return buffer[randomIndex];

if (!allowDuplicates)
buffer.RemoveAt(randomIndex);
}
}
 
M

Michael C

Peter Duniho said:
Ugh, no.

Morten and Markus both posted fairly _inefficient_ solutions. The swap
method is the most efficient, as it only involves copying data. The
"build a list, then remove elements" is inefficient in two ways: it
requires twice as much memory, and every time you remove an element from
the list, you have to copy (on average) half the list.

Other than the skewed random distribution bug in Philipp's code, his is in
fact the most desirable approach for the "shuffle" algorithm.

Ok, fair enough, I misread what Philipps code was actually doing, I thought
it was doing something different.

Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top