左程云高级班5
分析:
- 在整数集合中,0是个特殊的存在, 一般我们的进制是包含0的,在每一位上0作为空值用来填充。
- 比如十进制,表示120,分解为1 10^2 + 2 10 ^1 + 0 * 10 ^0;
- 再比如3进制,11 = 13^1 + 1 3^0 = 4;
- 本题中,如果集合中有3个元素,对应关系A:1, B:2,C:3; 那么AA利用3进制进行换算就是4,没有毛病。
- 可是,当把9换算成这种字母时候,因为9 = 1 * 3 ^ 2, 所以如果如果是正常三进制的话,字符串应该是100,1对应A,0没有对应字符。
- 我们这里采用的就是不含0的进制,称为伪进制,原来N进制每一位可以表示0~N-1,现在可以表示1 ~N,这样的话,碰到N不用进位, 在当前位上操作。比如CA表示十进制的10 = 33^1 + 13^0;
解法:假设N = 3进制
- 将字符转换成数字好转换,直接按照进制进行累加和。
- 将数字转换成字符,第一个想法是看 N的几次方,求出最大的指数,比如10, 3^2 =9 <10, 因为应该是有三位,但是可以比较原始题干中的CA=10可以看出,字符长度只有两位。
- 左程云提供的解法是,先从右往左每一位上赋上1,然后看剩余值能否被更高位的base补充,先找到最高位所在,在从左往右补足剩下的值。
我的代码:
public static void main(String[] args) {
int num = 13;
int n = 3;
System.out.println(num2String(num, n ));
}
public static int string2Num(String s, int n ){
int num = 0;
char[] chs = s.toCharArray();
for(int i = chs.length-1; i >=0; i--){
int base = (int) Math.pow(n, chs.length-1-i);
num += Integer.valueOf(String.valueOf(chs[i])) *base;
}
return num;
}
public static String num2String(int num , int n ){
int left = num -1;
int res = 1;
int len = 1;
for(int i = 1 ; left>0; i++){
int base = (int) Math.pow(n, i);
if(left >=base){
res = res<<1 | 1;
len++;
left -= base;
}else {
break;
}
}
int[] arr = new int[len];
for(int i = 0; i < arr.length; i++){
arr[i] = 1;
int base = (int) Math.pow(n, len -1-i);
arr[i] += left/base;
left = left - left/base * base;
}
return Arrays.toString(arr);
}
左程云的:
tips:
- 求每一位基数的时候,用连乘N的形式,免去了Math.pow()函数的多次调用
- 最后求剩余值的时候,直接用取余就可以得到,我上面的代码用了left = left - left/base * base; 脱了裤子放屁,比较繁琐。