开发者

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 number开发者_开发问答s 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.


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.


  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.


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.


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;


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...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜