I want to generate a 10 digit number, and non of its digit occur more than 3 times.
You are saying number, but integers cant start with zero. So you need to convert generated nunber to string and then add "00" + myGeneratedNumber like this.
The following should do the trick
int rndNumber = new Random().Next();
rndNumber.ToString().PadLeft(10, '0');
It should be noted that you will not get full coverage of the possible range from this (I believe int32 doesn't go high enough) and if you are generating more than one of these then suitably modify your random object to be reused rather than regenerated. If you need to cover the whole range then I'd probably be lazy and just generate two strings of length five using this method (limiting your random number to be five digits max) and put them together.
Edit: Actually, the best way to do this is probably as follows:
double rndNumber = new Random().NextDouble();
string testNumber = (rndNumber * 10000000000).ToString("0000000000.000");
Generates a random number between 0 and 1. Multiplies to get a number between 0 and 10000000000 (a 10 digit number at most) and then the ToString formats it correctly to be a 10 digit+ 3 decimial digits.
If you wanted to get rid of trailing zeros then you could do .TrimEnd('0').TrimEnd('.')
the TrimEnd('0')
will remove trailing zeros (so 0.100 would become 0.1) and the second TrimEnd('.')
will remove a trailing '.' in the event the number was a whole number.
If you need full coverage then I would suggest also making a random choice of whether you want the optional section as well and then changing the string format expression that you use. How you weight that choice will depend probably on whether you want to test the with and without equally or if you want to have a balanced spread of all the possibilities.
I wouldn't use the Random class in C#, rather use RNGCryptoServiceProvider in System.Security.Cryptography, its a much better random number generator, and you specify the length of the random returned.
New answer since its kind of a different question now...
The following code should do the job you're looking for.
private string GenerateString()
{
Random rnd = new Random();
List<char> availableNumbers = new List<char>{'0','1','2','3','4','5','6','7','8','9'};
Dictionary<char, int> counts = new Dictionary<char,int>();
for (int i = 0; i < 10; i++)
{
counts.Add(availableNumbers[i],0);
}
char[] generatedCharacters = new char[10];
for (int i = 0; i < generatedCharacters.Length; i++)
{
char digit = availableNumbers[rnd.Next(availableNumbers.Count)];
generatedCharacters[i] = digit;
counts[digit]++;
if (counts[digit] == 3)
availableNumbers.Remove(digit);
}
return new string(generatedCharacters);
}
Its possible this can be refined and I'm sure LINQ probably does it in one line but I'm not too hot with that. :)
Roughly speaking the idea is that we create a list of available numbers which starts with all the numbers in. We then have a dictionary to keep a count for each character (all 0 initially). For each character in our output string we randomly select a char from our availableNumbers and add it to the string. We then increment the count for that char and if it hits 3 we take it out of the available characters.
This function should not need any trial and error that you were talking about before to find a valid number. However, I'm not 100% sure whether it generates an even spread of outputs though I'm fairly sure it does).