左程云高级班5
    image.png
    image.png
    分析:

    • 在整数集合中,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补充,先找到最高位所在,在从左往右补足剩下的值。

    我的代码:

    1. public static void main(String[] args) {
    2. int num = 13;
    3. int n = 3;
    4. System.out.println(num2String(num, n ));
    5. }
    6. public static int string2Num(String s, int n ){
    7. int num = 0;
    8. char[] chs = s.toCharArray();
    9. for(int i = chs.length-1; i >=0; i--){
    10. int base = (int) Math.pow(n, chs.length-1-i);
    11. num += Integer.valueOf(String.valueOf(chs[i])) *base;
    12. }
    13. return num;
    14. }
    15. public static String num2String(int num , int n ){
    16. int left = num -1;
    17. int res = 1;
    18. int len = 1;
    19. for(int i = 1 ; left>0; i++){
    20. int base = (int) Math.pow(n, i);
    21. if(left >=base){
    22. res = res<<1 | 1;
    23. len++;
    24. left -= base;
    25. }else {
    26. break;
    27. }
    28. }
    29. int[] arr = new int[len];
    30. for(int i = 0; i < arr.length; i++){
    31. arr[i] = 1;
    32. int base = (int) Math.pow(n, len -1-i);
    33. arr[i] += left/base;
    34. left = left - left/base * base;
    35. }
    36. return Arrays.toString(arr);
    37. }

    左程云的:
    tips:

    • 求每一位基数的时候,用连乘N的形式,免去了Math.pow()函数的多次调用
    • 最后求剩余值的时候,直接用取余就可以得到,我上面的代码用了left = left - left/base * base; 脱了裤子放屁,比较繁琐。

    image.png
    image.png
    image.png
    image.png