1. 程式人生 > >[LeetCode] Convert a Number to Hexadecimal 數字轉為十六進位制

[LeetCode] Convert a Number to Hexadecimal 數字轉為十六進位制

Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used.

Note:

  1. All letters in hexadecimal (a-f) must be in lowercase.
  2. The hexadecimal string must not contain extra leading 0s. If the number is zero, it is represented by a single zero character '0'
    ; otherwise, the first character in the hexadecimal string will not be the zero character.
  3. The given number is guaranteed to fit within the range of a 32-bit signed integer.
  4. You must not use any method provided by the library which converts/formats the number to hex directly.

Example 1:

Input:
26

Output:
"1a"

Example 2:

Input:
-1

Output:
"ffffffff"

這道題給了我們一個數字,讓我們轉化為十六進位制,拋開題目,我們應該都會把一個十進位制數轉為十六進位制數,比如50,轉為十六進位制數,我們先對50除以16,商3餘2,那麼轉為十六進位制數就是32。所以我們就按照這個思路來寫程式碼,由於輸入數字的大小限制為int型,我們對於負數的處理方法是用其補碼來運算,那麼數字範圍就是0到UINT_MAX,即為16^8-1,那麼最高位就是16^7,我們首先除以這個數字,如果商大於等於10,我們用字母代替,否則就是用數字代替,然後對其餘數進行同樣的處理,一直到當前數字為0停止,最後我們還要補齊末尾的0,方法根據n的值,比-1大多少就補多少個0。由於題目中說明了最高位不能有多餘的0,所以我們將起始0移除,如果res為空了,我們就返回0即可,參見程式碼如下:

解法一:

class Solution {
public:
    string toHex(int num) {
        string res = "";
        vector<string> v{"a","b","c","d","e","f"};
        int n = 7;
        unsigned int x = num;
        if (num < 0) x = UINT_MAX + num + 1;
        while (x > 0) {
            int t = pow(16, n);
            int d = x / t;
            if (d >= 10) res += v[d - 10];
            else if (d >= 0) res += to_string(d);
            x %= t;
            --n;
        }
        while (n-- >= 0) res += to_string(0);
        while (!res.empty() && res[0] == '0') res.erase(res.begin());
        return res.empty() ? "0" : res;
    }
};

上述方法稍稍複雜一些,我們來看一種更簡潔的方法,我們採取位操作的思路,每次取出最右邊四位,如果其大於等於10,找到對應的字母加入結果,反之則將對應的數字加入結果,然後num像右平移四位,迴圈停止的條件是num為0,或者是已經迴圈了7次,參見程式碼如下:

解法二:

class Solution {
public:
    string toHex(int num) {
        string res = "";
        for (int i = 0; num && i < 8; ++i) {
            int t = num & 0xf;
            if (t >= 10) res = char('a' + t - 10) + res;
            else res = char('0' + t) + res;
            num >>= 4;
        }
        return res.empty() ? "0" : res;
    }
};

下面這種寫法更加簡潔一些,雖然思路跟解法二並沒有什麼區別,但是我們把要轉換的十六進位制的數字字母都放在一個字串中,按位置直接取就可以了,參見程式碼如下:

解法三:

class Solution {
public:
    string toHex(int num) {
        string res = "", str = "0123456789abcdef";
        int cnt = 0;
        while (num != 0 && cnt++ < 8) {
            res = str[(num & 0xf)] + res;
            num >>= 4;
        }
        return res.empty() ? "0" : res;
    }
};

參考資料: