Reputation: 9126
First off, this is not a homework assignment. I need to this solution for assigning device names for devices being attached to AWS EC2 instances. I'm working in Java.
I'm looking for a solution where I can define an arbitrary set of characters to serve as numerals to represent numbers of base N, and then be able to increment and decrement these values. For example, say I define a base-3 number system with the numeral set {f,g,h}. So starting in "0" in decimal and incrementing, we would have the sequence:
f, g, h, gf, gg, gh, hf, hg, hh
.
This needs to work with numbers larger than base-10, so a simple mapping between characters and roman numberals won't do the trick.
As for my specific use case, I'll be doing it with assigning device names attached to a machine, but certain letters are forbidden from being used, so I'll be defining a custom set of permitted characters.
I tried implementing this myself and quickly went down a rabbit hole of logic that was tripping me up. It seems like something someone else has likely implemented already, or at least part of it. Any ideas?
Upvotes: 0
Views: 84
Reputation: 65859
Something like this? I use a BigInteger
behind the scenes to avoid all overflows and just generate the number on the fly in toString
.
class Counter {
// My current value.
private BigInteger n;
// The character set to use.
private char[] digits = "0123456789".toCharArray();
public Counter() {
this(0);
}
public Counter(long start) {
n = BigInteger.valueOf(start);
}
public void inc() {
n = n.add(BigInteger.ONE);
}
public void dec() {
n = n.subtract(BigInteger.ONE);
}
public void setDigits(char[] digits) {
this.digits = digits;
}
public String toString() {
StringBuilder sb = new StringBuilder();
BigInteger base = BigInteger.valueOf(digits.length);
for (BigInteger v = n; v.compareTo(BigInteger.ZERO) > 0; v = v.divide(base)) {
sb.append(digits[v.mod(base).intValue()]);
}
return sb.length() == 0 ? "" + digits[0] : sb.reverse().toString();
}
}
private void test(String s) {
Counter counter = new Counter();
counter.setDigits(s.toCharArray());
for (int i = 0; i < 100; i++, counter.inc()) {
System.out.println(counter);
}
}
private void test() {
test("0123456789");
test("fgh");
test("QwErTyUiOpAsDfGhJkLzXcVbNm");
}
Upvotes: 0