W
W
Wan-Derer2020-11-06 14:31:35
Java
Wan-Derer, 2020-11-06 14:31:35

Multi-digit counter from numbers to any base (Java), how to do?

I get a positive integer N at the input.
I need to make N digits, each of which can take on the values ​​0 ... (N-1) and sort through them all.
Example:
N=3
combinations:
0 0 1
0 0 2
0 1 0
.......
2 2 2

N is not necessarily a number, it can be, for example, 27. So 27 digits, in each digit 0...26.
The idea is similar to hexadecimal numbers, but the base is not 16, but arbitrary. Java has a Biginteger that can be represented in bases up to 36. In principle, not bad, but I would like a more general solution.

Those. I take the least significant digit, click it up, as soon as it reaches N - I reset it and click up the next digit. I suspect that it is necessary to use recursion, but I can’t figure out how exactly :) Tell me the algorithm, who knows :)

I also suspect that a complete enumeration of combinations is a standard task, but in mathematics I’m pretty illiterate :(

PS: in general, the original task is simpler (more difficult) : combinations should not be all, but only unique elements, i.e. for N = 3 it will be:
0
1
2
0 1 (1 0 is the same combination, therefore we do not include)
0 2
1 2
0 1 2
but how I (sort of) know to do this with a complete enumeration - make a Set>, throw a TreeSet combination, and the finished TreeSet is already in the Set, it seems that it should turn out what you need.
But if there is a way without a complete enumeration - share, I will be grateful :)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
W
Wan-Derer, 2020-11-11
@Wan-Derer

In general, the idea of ​​a complete enumeration had to be abandoned - it takes too long to count. I tried both with recursion and with BigInteger representation based on N (regular and self-made) - do not wait :) I
solve the main problem in this way. Let's say N = 5. Then the "maximum" combination will be:
0, 1, 2, 3, 4
All the rest will be obtained from it by discarding elements.
First we throw out one at a time, then two at a time, and so on. Those. I need to sort out not the elements themselves, but their positions. I made something like a binary mask, in which "1" - leave the element, "0" - throw it away. For example:
0, 1, 2, 3, 4 - initial combination
0, 1, 0, 1, 0 - mask
-, 1, -, 3, -> 1, 3 - result
It remains to go through all the mask options, and this is just an increment of the whole - and all combinations are obtained! Also not fast, but much faster than brute force! If someone knows how else you can speed it up - share :)
And yes, collecting all the combinations in an array is also a dead idea: the memory ends very quickly :) You have to process each combination "on the spot".
kott:

public class Part {
    public static void main(String[] args) {
        int numberOfThings = 41;
        long top = ((long) Math.pow(2, numberOfThings + 1));
        long bottom = ((long) Math.pow(2, numberOfThings)) + 1;

        int[] things = new int[numberOfThings];
        for (int i = 0; i < numberOfThings; i++) {
            things[i] = i;
        }

        while (bottom != top) {
            char[] mask = Long.toBinaryString(bottom++).toCharArray();

            List<Integer> comb = new ArrayList<>();
            for (int i = 0; i < numberOfThings; i++) {
                if (mask[i + 1] == '1') comb.add(things[i]);
            }

            // Обработка комбинации
            System.out.println(comb);
        }

    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question