简体   繁体   中英

How can I count if a specific set of digits are present in an array

Suppose I have a number 123. I need to see if I get all digits 1 through 9, including 0. The number 123 has three digits: 1,2, and 3. Then I multiply it by 2 and get 246 (I get digits 2, 4, 6). Then I multiply it by 3 and I get 369. I keep doing incremental multiplication until I get all digits.

My approach is the following:

public int digitProcessSystem(int N) {
 String number = Integer.toString(N);
 String [] arr = number.split("");
// List <Integer> arr2 = new ArrayList<>();
 for (Integer i = 0; i < arr.length; i++) {
     try {

         arr2[i] = Integer.parseInt(arr[i]);
     } catch (NumberFormatException e) {
         }
     }

 count =0;
 boolean contains = IntStream.of(arr2).anyMatch(x -> x == 1|| x==2 ||x ==  3|| x==4|| x == 5|| x==6 ||x == 7|| x==8||x == 9|| x==0);

}

I really don't know how can I keep doing the boolean for digits that did not match in the first trail above because I will definitely get any one of the all digits in the above boolean search. How can I get that if some specific digits are present and some are not so that I can multiply the actual number to do the search for the digits that were not found in the first trial; just like the way I defined in the beginning.

You could wrap that into a while loop and include the numbers into a Set . Once the set has the size 10 all digits are present in the number. I´d also suggest to use a long instead of an int or you´ll be getting wrong results or run into an excpetion. Here´s some example code for this:

private static long digitProcessSystem(long N) {
    long numberN = N;
    String number = Long.toString(N);
    // calculate 10 digits number here yet
    if (number.length() < 10) {
        // using the smallest possible number with each digit
        // By using this number we are most likely allmost at the result
        // This will increase the performance for small digits heavily.
        long divider = 1023456789L / numberN;
        numberN *= divider;
    }
    number = Long.toString(numberN);
    String[] arr = number.split("");
    Set<String> input = new HashSet<>(Arrays.asList(arr));
    while(input.size() != 10){
        // add N to number
        numberN += N;
        // Parse the new number
        number = Long.toString(numberN);
        // split
        arr = number.split("");
        // clear set
        input.clear();
        // Add the new numbers to the set. If it has the size 10 now the loop will stop and return the number.
        input.addAll(Arrays.asList(arr));
    };
    return numberN;
}

public static void main(String[] args) {
    System.out.println(digitProcessSystem(123));
}

output:

1023458769

I'm not sure what is your end goal. But you can use a HashSet and do something like this in order to achieve what you are trying to achieve:

public static void main (String[] args) throws Exception {
    long number = 123L, counter = 1000000000L / number;
    while(digitProcessSystem(number * counter++));
    System.out.println("Number: " + number * (counter - 1));
}

public static boolean digitProcessSystem(long input) {
    char[] arr = Long.toString(input).toCharArray();
    Set<Character> set = new HashSet<>();
    for (int i = 0; i < arr.length; i++) {
        set.add(arr[i]);
    }
    return set.size() != 10;
}

Output:

Number: 1023458769

without using java language Facilities and hashset:

private static long digitProcessSystem(long N) {
long numberN = N;
String number = Long.toString(N);
String[] arr = number.split("");;
int arr2=new int[10];
int sum=0;
while(sum != 10){
    sum=0;
    // add N to number
    numberN += N;
    // Parse the new number
    number = Long.toString(numberN);
    // If it doesn´t have 10 digitis continue here yet
    if(number.length() < 10) continue;
    // split
    arr = number.split("");
    for(int i=0;i<arr.length;i++){
        arr2[arr]=1;
    }
    for(int i=0;i<10;i++){
        sum+=arr2[i];
    }
};
return numberN;
}

Generally, if you want to process the characters of a String , don't do it by splitting the string into substrings. Note that every CharSequence , including String , has the methods chars() and codepoints() allowing to process all characters as IntStream .

To check whether all digits from '0' to '9' are present, we can use chars() (don't have to think about surrogate pairs) and do it straight-forward, map them to their actual number by subtracting '0' , filter out all non-digits (just to be sure), then, map them to an int where the n th bit is set, so we can binary or them all together and check whether all of the lowest ten bits are set:

public static boolean hasAllDigits(String s) {
    return s.length()>9 &&
        s.chars().map(c -> c-'0').filter(c -> c>=0 && c<=9)
                 .map(c -> 1 << c).reduce(0, (a,b)->a|b) == 0b1111111111;
}

As a bonus, a length-check is prepended as a String must have at least ten characters to contain all ten digits, so we can short-cut if it hasn't.


Now, I'm not sure about your actual task. If you just want to iterate until encountering a number having all digits, it's quite simple:

long number=123;
for(long l = 1, end = Long.MAX_VALUE/number; l < end; l++) {
    long candidate = number * l;
    if(hasAllDigits(String.valueOf(candidate))) {
        System.out.println("found: "+candidate);
        return;
    }
}
System.out.println("not found within the long range");

But if you want to know when you encountered all digits within the sequence of numbers, we have to adapt the test method and keep the bitset between the iterations:

public static int getDigits(String s) {
    return s.chars().map(c -> c-'0').filter(c -> c>=0 && c<=9)
            .map(c -> 1 << c).reduce(0, (a,b)->a|b);
}

long number=123;
int digits=0;
for(long l = 1, end = Long.MAX_VALUE/number; l < end; l++) {
    long candidate=number * l;
    int newDigits=digits | getDigits(String.valueOf(candidate));
    if(newDigits != digits) {
        System.out.printf("pos %10d: %10d%n", l, candidate);
        digits=newDigits;
        if(digits == 0b1111111111) {
            System.out.println("encountered all digits");
            break;
        }
    }
}
if(digits != 0b1111111111) {
    System.out.println("did not encounter all digits within the long range");
}

This method will only print numbers of the sequence which have at least one digit not encountered before, so you can easily see which one contributed to the complete set and will see at most ten numbers of the sequence.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM