领扣(LeetCode)数字转换为十六进制数 个人题解
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
- 十六进制中所有字母(
a-f
)都必须是小写。 - 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符
'0'
来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。 - 给定的数确保在32位有符号整数范围内。
- 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
示例 1:
输入: 26 输出: "1a"
示例 2:
输入: -1 输出: "ffffffff"
首先拿到这题,比较简单的一个思路是把负数转换为正数的形式(因为我们知道,负数在计算机中的存放值=2^N+该负数,N为存储的位数)。但是在JAVA中,这个思路会在num值为-1的情况下出现下标溢出的情况。这个问题还不知道原因。
于是我百度了一下,发现了一个更优秀的做法。也就是模拟电路加减的做法,把数字拿去和0xf相与,得到的结果就是数字的最后四位二进制代表的十进制数值。然后继续把该数字算术右移四位,也就是相当于得到下一个四位二进制的值,以此类推。通过二进制的做法,规避了操作十进制数时负数的问题。
在这题里使用位运算需要注意不要超出八位数,因为负数的算术右移可以在正常右移结束后得到非零值,循环不会正确退出。
代码如下:
1 class Solution { 2 public String toHex(int num) { 3 if (num == 0) 4 return "0"; 5 char[] pat = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 6 String ans = ""; 7 while (num != 0 && ans.length() <= 8) 8 { 9 ans = pat[num & 0xf] + ans; 10 num >>= 4; 11 } 12 return ans; 13 14 } 15 }