Reputation: 411
I need to output large numbers like for example 847288609443
as 3⁴⁵
. All of my numbers have the form 3^n
or 3^n -1
. I use the hints from this post. For now my code looks like :
public static void main(String[] args) throws IOException {
Map<String,Character> map = new HashMap<>();
map.put("-", '\u207b'); map.put("5", '\u2075');
map.put("0", '\u2070'); map.put("6", '\u2076');
map.put("1", '\u00b9'); map.put("7", '\u2077');
map.put("2", '\u00b2'); map.put("8", '\u2078');
map.put("3", '\u00b3'); map.put("9", '\u2079');
map.put("4", '\u2074');
for(int i = 1; i< 50; i++){
String [] s = String.valueOf(i).split("");
StringBuilder sb = new StringBuilder();
sb.append("3");
Stream.of(s).forEach(e->sb.append(map.get(e)));
System.out.println(sb.toString());
}
}
unicode values are from this wiki page:(https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts)
Is there another way of doing such a conversion instead of spliting the string value of my exponents and appending unicode chars?
Upvotes: 1
Views: 186
Reputation: 726779
You can implement this as a mapping of codepoints. Here is an implementation for non-negative numbers:
private static final int[] superCodepoint = new int[] {
'\u2070', '\u00b9', '\u00b2', '\u00b3', '\u2074', '\u2075', '\u2076', '\u2077', '\u2078', '\u2079'
};
public static String ToSuperscript(String s) {
return s.codePoints()
.map(c -> Character.isDigit(c) ? superCodepoint[Character.digit(c, 10)] : c)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
Upvotes: 1
Reputation: 59233
I'm going to assume that your code does what you want...
The idea of converting each digit to a unicode superscript and appending to a StringBuilder is fine, but your implementation is not very efficient -- especially in the split. If that's bothering you, then you can do it like this, which will be a lot faster:
static final String SUPDIGITS = "\u2070\u00b9\u00b2\u00b3\u2074\u2075\u2076\u2077\u2078\u2079";
public static void main(String[] args) throws IOException {
StringBuilder sb = new StringBuilder();
for(int i = 1; i< 50; i++) {
sb.setLength(0);
//append digits in reverse order
int v = i;
for (;v>0;v/=10) {
sb.append(SUPDIGITS.charAt(v%10));
}
//and then the 3
sb.append("3");
//and then reverse it
sb.reverse();
System.out.append(sb).println();
}
}
The major difference here is that this version does many fewer memory allocations.
Upvotes: 2
Reputation: 9650
You could do something like that:
private static char[] DIGITS = {
'\u2070', '\u00b9', '\u00b2', '\u00b3', '\u2074',
'\u2075', '\u2076', '\u2077', '\u2078', '\u2079'};
public static String toSuperscript(int i) {
boolean neg = i < 0;
if (neg) {
i = -i;
}
char[] chars = new char[15];
int k = chars.length;
do {
chars[--k] = DIGITS[i%10];
i /= 10;
} while (i > 0);
if (neg) {
chars[--k] = '\u207b'; // minus sign
}
return new String(chars, k, chars.length-k);
}
public static void main(String[] args) throws IOException {
for(int i = 1; i< 50; i++){
System.out.println("3" + toSuperscript(i));
}
}
Upvotes: 2