316,045
社区成员
发帖
与我相关
我的任务
分享36进制由0-9,a-z,共36个字符表示。
要求按照加法规则计算出任意两个36进制正整数的和,如1b + 2x = 48 (解释:47+105=152)
要求:不允许使用先将36进制数字整体转为10进制,相加后再转回为36进制的做法
36进制的加法毕竟也是数学里的一种加法运算,依然遵循加法进位的原则,只不过之前的十进制加法是满十进位,而36进制加法是满36进一。于是按照进位思想来进行代码编写,由于需要相加运算的时候需要使用十进制,相加之后又需要将结果转成36进制,所以我在这里写了两个工具方法getChar和getInt将参数转为36进制和10进制。
首先和十进制加法运算一样,是从低位开始进行运算,所以需要获取两位加数的长度,从后往前循环运算。循环体也就是运算过程就是进位的过程,定义了一个carry用来记录进位数。这里以1b + 2x为例,进入for循环第一次将"b"和"x"转换为十进制11和33,十进制相加为44,44大于36肯定会产生进位,进位数就是44对36取模carry=1,余数使用getChar转换为36进制就是结果的个位数,StringBuilder 的sb就是用来接收36进制加法的结果。循环体前两行的三目运算赋值可以用来应对最高位运算后依然有进位的情况,在这个情况下carry肯定是个大于0的正整数,两位的位数已算完故此时ij都为负数,剩下的的就是进位carry转36进制了。
最后我们StringBuilder 的sb结果是从个位开始运算的,所以sb也要倒序输出才是最终结果。
public class HelloWorld {
static String add(String a, String b) {
int i = a.length() - 1, j = b.length() - 1;
int carry = 0;
StringBuilder sb = new StringBuilder();
for (; i >= 0 || j >= 0 || carry > 0 ; i--,j--) {
int x = i >= 0 ? getInt(a.charAt(i)) : 0;
int y = j >= 0 ? getInt(b.charAt(j)) : 0;
int sum = x + y + carry;
sb.append(getChar(sum % 36));
carry = sum / 36;
}
return sb.reverse().toString();
}
/**
* 将十进制整数转化为 36进制字符
* @param n
* @return
*/
public static char getChar(int n) {
if (n <= 9) {
return (char) (n + '0');
} else {
return (char) (n - 10 + 'a');
}
}
/**
* 将36 进制字符转化为 10进制整数
* @param c
* @return
*/
public static int getInt(char c) {
if (c <= '9') {
return c - '0';
} else {
return c - 'a' + 10;
}
}
public static void main(String[] args) {
System.out.println(add("1b", "2x" ));
}
}