Tuesday, July 14, 2009

Validating Numbers in C#?

I have generated four random numbers between 1 and 5 in a C# program, rndNumberA, rndNumberB, rndNumberC, rndNumberD..





I need to make sure none of the numbers are the same, and assign a new number if they are.





Can anyone help?





Thanks in advance : )

Validating Numbers in C#?
do


{


//generate the numbers


}


while(rndNumberA==rndNumberB %26amp;%26amp; rndNumberB == rndNumberC %26amp;%26amp; rndNumberC == rndNumberA)
Reply:If you know your search space (for example, unique numbers between 1 and 5) then allocate them into an array. When selecting a random element, select a random index into this array, use the value at that index and remove the element from the array. This is the best way to do it and ensure it runs in constant time. If you generated the numbers first, and then checked for duplicates, you would not be able to guarantee that any replacement number is unique and therefore the program could run forever in an infinite loop (bad).





List%26lt;int%26gt; searchSpace = new List%26lt;int%26gt;(new int[] { 1, 2, 3, 4, 5 });


List%26lt;int%26gt; results = new List%26lt;int%26gt;();





for (int i = 0; i %26lt; 5; i++)


{


int randomIndex = random.Next(searchSpace.Count);


results.Add(searchSpace[randomIndex]);


searchSpace.RemoveAt(randomIndex);


}





// results will contain a list of numbers from 1 to 5, each being unique and random
Reply:var randomNumber = new List%26lt;int%26gt;(4);


var random = new System.Random();





while (randomNumber.Count %26lt; 4)


{


var pseudo = random.Next(1, 5);


if (!randomNumber.Contains(pseudo))


{


randomNumber.Add(pseudo);


}


}





foreach (var number in randomNumber)


{


Console.WriteLine(number);


}
Reply:Basically, I would do this in a loop, and store the numbers, as they are generated in an array. If you know that there are going to be 4 numbers chosen, you can declare a static array with four positions. There are a couple of different ways you could go about checking to make sure there are no duplicates. You could generate all four numbers and assign each of them to the array, then loop through the array checking for dup's, OR, you could actually generate the randoms in the loop itself, and check against the previous numbers entered. You would need to define rules for what number would be used to replace the duplicate as well. If you get some code going, and post it, I will be glad to help you refine it. Good luck.
Reply:I went with a recursive solution:





static Random generator = new Random(); //global variable to generate random numbers





static void Main(string[] args)


{


List%26lt;int%26gt; numbers = new List%26lt;int%26gt;();//list to hold results





const int LOOPS = 4;


const int MIN=1;


const int MAX=5;


for (int i = 0; i %26lt; LOOPS; i++)


{


AssignNumbers(numbers,MIN,MAX);





}





for (int i = 0; i %26lt; numbers.Count; i++)


{


Console.WriteLine(numbers[i].ToString())...


}


}


//************************************...


//assigns a number. If the list has a number, recurses again.





static void AssignNumbers(List%26lt;int%26gt; list,int min, int max)


{


int temp = GetNumber(min, max);


if (!list.Contains(temp))


{


list.Add(temp);


}


else


{


AssignNumbers(list,min,max);


}


}


//************************************...





//Helper function to assign the random numbers.


static int GetNumber(int min, int max)


{


return generator.Next(min, max + 1);


}





}
Reply:A basic solution (forgive hardcoding of index limits) :





Do a for.. loop through an array of your number range, and for each index, generate a random index 0..4 with which you swap values in the array, and then just take the values at indices 0..3.......





int[] aiPool = new int[] { 1, 2, 3, 4, 5 };


Random rnd = new Random();


for (int iIndex = 0; iIndex %26lt; 5; iIndex++)


{


int iRandomIndex = Random.Next(5);


// Swap values at iIndex and iRandomIndex


int iCopy = aiPool[iIndex];


aiPool[iIndex] = aiPool[iRandomIndex];


aiPool[iRandomIndex] = iCopy;


}





rndNumberA = aiPool[0];


rndNumberB = aiPool[1];


rndNumberC = aiPool[2];


rndNumberD = aiPool[3];





Each rndNumberX is guaranteed to be unique, and will be random as every index in the pool is swapped.





This approach ensures that the minimum of calls to Random.Next are made and no "seen that" tracking is needed.





Vera - your approach I think should use || instead of %26amp;%26amp; as the condition a=1, b=1, c=2 ends the loop, but does not enforce uniqueness. Also, you would need 3+2+1 comparisons - a-b, a-c, a-d, b-c, b-d and c-d


No comments:

Post a Comment