How to generate random numbers with restrictions on like numbers and powers of ten
We need to generate random numbers within a certain digit range with few restrictions
e.g. For double digit range 11 - 99, the resultant output should not include all like numbers [11,22,33,44,...99] and multiples of 10 [2开发者_高级运维0,30,40....90]
The resultant output should be [12,13,14,15,16,17,18,19,21,23,...98]
Note: This function should work seamlessly for other digit ranges also (e.g. 3 digit ranges spanning 101 - 999 and four digit ranges spanning 1001 - 9999)
We are having difficulties in identifying like numbers (e.g 11, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333, ...., 3333 ...)
EDIT1:
protected static List<Integer> fetchRandIntegers(int min, int max, int howMany, boolean randomize) {
// We need to reverse minimum, maximum values for negative ranges
if (min > max) {
int tmp = min;
min = max;
max = tmp;
}
List<Integer> allNumbers = new ArrayList<Integer>();
for (int i = min; i <= max; i++) {
allNumbers.add(i);
}
if (randomize) {
...
}
return allNumbers;
}
To identify if integer i
has all digits the same:
- Convert
i
tostring
and compare the characters, or - Repeatedly modulo and divide by 10 and check if all modulos are the same
with something like:
public boolean hasAllDigitsSame (int i)
{
int a = i ;
int m = a % 10 ;
int mm = m ;
while(a > 0)
{
m = a % 10;
if (m != mm)
return False ;
a /= 10 ;
}
return True ;
}
To identify if integer i
is a multiple of 10
(100, 1000):
- Check if
i modulo 10
is0
.
Two simple options:
- Generate any random number in the range, and do it again (and again...) if you pick a "banned" one
- Work out how many eligible numbers you actually have, generate a number in the range [0..size) and then map that onto an eligible number
The latter is potentially more efficient (you don't loop around generating numbers which are then discarded), but more complicated to implement.
EDIT: Here's a method to check whether all the digits in an integer are the same:
public boolean checkForAllOneDigit(int value)
{
int digit = value % 10;
value = value / 10;
while (value > 0)
{
if (value % 10 != digit)
{
return false;
}
value = value / 10;
}
return true;
}
(There may be a slightly more elegant way of writing the loop, but I haven't had coffee yet... the "modulo 11 or 111 or 1111 etc" approach is really neat too.)
This program will also give the answer
import java.util.*;
public class Generate {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("\nEnter the limit:");
int k = scan.nextInt();
int i,j,w,l,q,d;
for(i=13;i<=k;i++)
{
j=i%10;
if(j!=0)
{
if(i<99)
{
for(w=1;w<=9;w++)
{
l=11*w;
if(l==i)
{
i++;
continue ;
}
}
}
if(i>99)
{
for(q=1;q<=9;q++)
{
d=111*q;
if(d==i)
{
i++;
continue ;
}
}
}
System.out.println(i);
}
}
}
}
I know this program is quite big, just to give an idea ,i have given this.But i am sure it will give correct answer !!
how big a lookup table are you willing to use? (Map consecutive range to the bigger range that doesn't have your forbidden values.)
Or do your check (if under 100, multiples of 10 and 11, if under 1000 multiples of 111 and 100, and so on), and if the fish is too small throw it back?
精彩评论