Geo Ego
Geo Ego

Reputation: 1335

Random string of numbers excluding specific digits

I'm working on a .NET application in C# that will generate a variable-length string of random digits. I'd like to add a checklist that will allow the user to select any combination of digits between zero and nine and prevent them from appearing in the string. Currently, I simply do this to get the string:

do
{
   int num = rnd.Next(10);
   output += num.ToString();
   i++;
}
while (i < stringLength);

I can think of a way to exclude selected digits by throwing them out once they are generated and not incrementing the counter, but it seems like there would be a less wasteful algorithm. The program will support generating a number of strings, so if a user is creating millions of strings, I'd like to keep overhead at a minimum.

Bonus: I forgot to mention that I'd also like if someone could point me to a resource for patterns such as this. I'll be working a lot with random numbers based on parameters in the near future and I'd like to learn some principles instead of asking questions about individual problems such as this.

Upvotes: 1

Views: 4537

Answers (5)

ChrisF
ChrisF

Reputation: 137148

If you generate an array of allowed characters then pick from that:

int[] allowedDigits = {1, 2, 3, 6, 7, 0};
var output = new StringBuilder();

do
{
   int num = rnd.Next(allowedDigits.Length);
   output.Append(allowedDigits[num]);
   i++;
}
while (i < stringLength);

obviously allowedDigits is generated rather than hard coded ;)

Using a StringBuilder is more efficient and you don't have to explicitly do the ToString.

Upvotes: 15

Massif
Massif

Reputation: 4433

Just for a laugh, here's a gratuitously "clever-clever" way of doing it:

int allowedDigits = {1, 3, 5, 4, 9};

//Generate an infinite sequence of numbers, 
//so be careful not to do foreach over it!
IEnumerable<int> GenerateNumbers(int max)
{
   while(true)
   {
      yield return rnd.Next(max);
   }
}

var filteredNumbers = from num in GenerateNumbers(10)
                      where num in allowedDigits
                      select num;

output = String.Join("", fitleredNumbers.Take(stringLength));

(or words to that effect, no compiler to check it with at the mo...)

It goes without saying that this is probably hopelessly inefficient...

Upvotes: 0

Javed Akram
Javed Akram

Reputation: 15344

int [] excludeNum={2 , 3 , 4}; 
do
{
   int num = rnd.Next(10);
   if(excludeNum.Contains(num))
      continue;
   output += num.ToString();
   i++;
}
while (i < stringLength);

By using continue statement you can change flow of control back to while(); without incrementing i;

Upvotes: 0

Fun Mun Pieng
Fun Mun Pieng

Reputation: 6891

string[] num = new string[9];
int j = 0;
for(int k = 0; k < num.length; k++)
  if (k != numToExclude)
    num[j++] = k.ToString();
}
StringBuilder output = new StringBuilder(stringLength);
do
{
   int n = rnd.Next(10);
   output.Append(num[n]);
   i++;
}
while (i < stringLength);

In the code above, you may change the num data type char. Not sure if that optimizes anything.

Upvotes: 0

Brent Worden
Brent Worden

Reputation: 10974

  1. create an array of length n, holding the chosen digits.
  2. generate random number between 0 and n-1, inclusive
  3. use the random number as an array index to select the digit.

Upvotes: 4

Related Questions