题目描述
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
- 十六进制中所有字母(
a-f
)都必须是小写。 - 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符
'0'
来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。 - 给定的数确保在32位有符号整数范围内。
-
不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
示例 1:
输入:
26
输出:
"1a"
示例 2:
输入:
-1
输出:
"ffffffff"
解题思路
首先要知道16进制数在计算机中是怎么表示的,由于对于16进制一个有16个数(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f)所以我们只需要使用4位 2^4=16刚好可以表示16个数,所以计算机在内部是用4位来表示16进制的0000表示0,0001表示1.....1111表示f。
所以题目给我们一个int型的数字num,一个int= 4字节 = 32位,这个32位数字可以被分隔成8个4位数,所以我们只需要从头到尾每4位每4的的遍历,每遍历一个4位就将其转化为16进制的数即可。有人可能会问为什么这样可以,其实这样我们是做了两个步骤,先转化为2进制(由于计算机中所有东西本身就是2进制存储的,所以我们可以直接得到该数字的2进制),再转化为16进制,比如对于26 ->二进制为00011010(前面省略了24个0)所以每4位遍历就变成了0001,1010对于0001 对应16进制中的1,1010对应16进制中的a所以结果就是为1a.所以对于此题我们只需要从尾部开始用位运算取出每一个4位,再转化为16进制即可只需要注意前面为0的16进制应该删除即可。
我们首先需要设一个数字calc = 0xf也就是右边4位为1其余均为0,此时我们把数字num与之进行与运算就可以取出,num右边4位的值,然后再把calc向左边移动4位就变成了11110000(前面省略24个0)此时在与之相与就可以得到num中右边8位的值,此时还需要把这个值向右移动4位,因为这样是的到了第2个4位值,然后再次重复此步骤即可。
代码实现
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class Solution {
public:
const char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f'};
string toHex(int num) {
if (num == 0) return "0";
string res;
unsigned int n = num;
unsigned int calc = 0xf;
unsigned int temp = 0xf;
int trans = 0;
for (int i = 0; i < 8; i++) {
temp = num&calc;
temp >>= trans;
res += map[temp];
calc <<= 4;
trans += 4;
}
for (int i = res.size()-1; i >= 0; i--) {
if (res[i] == '0') {
res.pop_back();
} else {
reverse(res.begin(), res.end());
return res;
}
}
return nullptr;
}
};