題目描述
實現一種整數編碼方法,使得待編碼的數字越小,編碼后所占用的字節數越小。
編碼規則如下:
編碼時7位一組,每個字節的低7位用于存儲待編碼數字的補碼
字節的最高位表示后續是否還有字節,置1表示后面還有更多的字節,置0表示當前字節為最后一個字節。
采用小端序編碼,低位和低字節放在低地址上。
編碼結果按16進制數的字符格式輸出,小寫字母需轉換為大寫字母
輸入描述
輸入的為一個字符串表示的非負整數
待編碼的數字取值范圍為[0,1<<64 - 1]
輸出描述
輸出一個字符串,表示整數編碼的16進制碼流
用例
輸入 | 0 |
輸出 | 00 |
說明 | 輸出的16進制字符,不足兩位的前面補0,如00、01、02。 |
輸入 | 100 |
輸出 | 64 |
說明 | 100的二進制表示為0110 0100,只需要一個字節進行編碼; 字節的最高位置0,剩余7位存儲數字100的低7位 (110 0100) ,所以編碼后的輸出為64。 |
輸入 | 1000 |
輸出 | E807 |
說明 | 1000的二進制表示為0011 1110 1000,至少需要兩個字節進行編碼; 第一個字節最高位置1,剩余的7位存儲數字1000的第一個低7位 (1101000),所以第一個字節的二進制為1110 1000,即E8; 第二個字節最高位置0,剩余的7位存儲數字1000的第二個低7位 (0000111),所以第一個字節的二進制為0000 0111,即07; 采用小端序編碼,所以低字節E8輸出在前,高字節07輸出在后。 |
主要思路如下:
- 將輸入的非負整數轉換成二進制字符串。
- 將二進制字符串按照7位一組進行編碼,每個字節的低7位用于存儲待編碼數字的補碼。
- 字節的最高位表示后續是否還有字節,置1表示后面還有更多的字節,置0表示當前字節為最后一個字節。
- 采用小端序編碼,低位和低字節放在低地址上。
- 將編碼結果按16進制數的字符格式輸出,小寫字母需轉換為大寫字母。
以上提供的代碼分別是Python、Java、C/C++和JS的實現,你可以選擇其中一種適合你的編程環境和喜好的語言進行使用。
題解代碼
Python題解代碼
num = int(input())
# 將待編碼數字轉換成二進制字符串
binaryStr = bin(num)[2:]
result = ''# 每7位一組進行編碼
for end in range(len(binaryStr), 0, -7):# 取出當前組需要編碼的二進制字符串currentBinaryStr = binaryStr[max(end - 7, 0):end]# 判斷當前字節是否為最后一個字節,設置最高位flag = '1' if end - 7 > 0 else '0'# 將當前字節轉換成十進制數decimal = int(flag + currentBinaryStr, 2)# 將當前字節的十六進制字符串形式添加到結果中hexStr = hex(decimal)[2:].upper()# 如果十六進制字符串長度為1,需要在前面補0hexStr = '0' + hexStr if len(hexStr) == 1 else hexStr# 將當前字節的十六進制字符串形式添加到結果中result += hexStr# 返回編碼結果的十六進制字符串形式
print(result)
JAVA題解代碼
/*** 實現一個整數編碼方法* 使得待編碼的數字越小* 編碼后所占用的字節數越小* 編碼規則如下:* 1.編碼時7位一組,每個字節的低7位用于存儲待編碼數字的補碼* 2.字節的最高位表示后續是否還有字節,置1表示后面還有更多的字節,* 置0表示當前字節為最后一個字節* 3.采用小端序編碼,低位和低字節放在低地址上* 4.編碼結果按16進制數的字符格式進行輸出,小寫字母需要轉化為大寫字母*/
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);long num = scanner.nextLong();// 將待編碼數字轉換成二進制字符串String binaryStr = Long.toBinaryString(num);StringBuilder result = new StringBuilder();// 每7位一組進行編碼for (int end = binaryStr.length(); end > 0; end -= 7) {// 取出當前組需要編碼的二進制字符串String currentBinaryStr = binaryStr.substring(Math.max(end - 7, 0), end);// 判斷當前字節是否為最后一個字節,設置最高位char flag = (end - 7 > 0) ? '1' : '0';// 將當前字節轉換成十進制數int decimal = Integer.parseInt(flag + currentBinaryStr, 2);// 將當前字節的十六進制字符串形式添加到結果中String hexStr = Integer.toHexString(decimal);// 如果十六進制字符串長度為1,需要在前面補0hexStr = (hexStr.length() == 1) ? "0" + hexStr : hexStr;// 將小寫字母轉換為大寫字母,并將當前字節的十六進制字符串形式添加到結果中result.append(hexStr.toUpperCase());}// 返回編碼結果的十六進制字符串形式System.out.println( result.toString());}}
C/C++題解代碼
#include <iostream>
#include <string>
#include <bitset>
#include <sstream>
#include <algorithm>
using namespace std;int main() {long num;cin >> num;// 將待編碼數字轉換成二進制字符串string binaryStr = bitset<64>(num).to_string();size_t start = binaryStr.find_first_not_of('0');if (start != string::npos) {binaryStr = binaryStr.substr(start);} else {binaryStr = "0";}stringstream result;// 每7位一組進行編碼for (int end = binaryStr.length(); end > 0; end -= 7) {// 取出當前組需要編碼的二進制字符串string currentBinaryStr = binaryStr.substr(max(end - 7, 0), end - max(end - 7, 0));// 判斷當前字節是否為最后一個字節,設置最高位char flag = (end - 7 > 0) ? '1' : '0';// 將當前字節轉換成十進制數int decimal = stoi(string(1, flag) + currentBinaryStr, nullptr, 2);// 將當前字節的十六進制字符串形式添加到結果中stringstream hexStr;hexStr << hex << decimal;// 如果十六進制字符串長度為1,需要在前面補0if (hexStr.str().length() == 1) {result << "0";}// 將小寫字母轉換為大寫字母,并將當前字節的十六進制字符串形式添加到結果中result << hexStr.str();}string rt = result.str();transform(rt.begin(), rt.end(), rt.begin(), ::toupper);// 返回編碼結果的十六進制字符串形式cout << rt << endl;return 0;
}
JS題解代碼
const readline = require("readline");// 創建readline接口實例
const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});// 監聽line事件,當輸入數據時觸發回調函數
rl.on("line", (line) => {// 將輸入的非負整數轉換為二進制字符串const binStr = BigInt(line).toString(2);// 定義一個數組來存儲編碼結果const ans = [];// 從二進制字符串的末尾開始,每七位一組進行編碼let end = binStr.length;while (end - 7 > 0) {// 將每一組轉換為十六進制字符串,并添加到結果數組中ans.push(parseInt("1" + binStr.substring(end - 7, end), 2).toString(16).padStart(2, '0').toUpperCase());// 更新末尾位置end -= 7;}// 處理最后一組,如果有剩余的位數不足七位,則直接編碼if (end >= 0) {ans.push(parseInt(binStr.substring(0, end), 2).toString(16).padStart(2, '0').toUpperCase());}// 將編碼結果數組拼接為一個字符串,并輸出console.log(ans.join(""));
});
代碼OJ評判結果
通過測試點
代碼講解
Python題解代碼講解
- 輸入處理: 通過
input()
函數獲取待編碼的非負整數。 - 二進制轉換: 使用
bin()
函數將待編碼數字轉換為二進制字符串,并去掉開頭的’0b’。 - 循環編碼: 從二進制字符串的末尾開始,每7位一組進行編碼。
- 取出當前組需要編碼的二進制字符串。
- 判斷當前字節是否為最后一個字節,設置最高位。
- 將當前字節轉換成十進制數,然后轉換為十六進制字符串。
- 如果十六進制字符串長度為1,需要在前面補0。
- 將當前字節的十六進制字符串形式添加到結果中。
- 輸出結果: 將編碼結果的十六進制字符串形式輸出。
JAVA題解代碼講解
- 輸入處理: 使用
Scanner
獲取待編碼的非負整數。 - 二進制轉換: 使用
Long.toBinaryString()
將待編碼數字轉換為二進制字符串。 - 循環編碼: 從二進制字符串的末尾開始,每7位一組進行編碼。
- 取出當前組需要編碼的二進制字符串。
- 判斷當前字節是否為最后一個字節,設置最高位。
- 將當前字節轉換成十進制數,然后轉換為十六進制字符串。
- 如果十六進制字符串長度為1,需要在前面補0。
- 將小寫字母轉換為大寫字母,并將當前字節的十六進制字符串形式添加到結果中。
- 輸出結果: 將編碼結果的十六進制字符串形式輸出。
C/C++題解代碼講解
- 輸入處理: 使用
cin
獲取待編碼的非負整數。 - 二進制轉換: 使用
bitset
將待編碼數字轉換為64位的二進制字符串。 - 循環編碼: 從二進制字符串的末尾開始,每7位一組進行編碼。
- 取出當前組需要編碼的二進制字符串。
- 判斷當前字節是否為最后一個字節,設置最高位。
- 將當前字節轉換成十進制數,然后轉換為十六進制字符串。
- 如果十六進制字符串長度為1,需要在前面補0。
- 將小寫字母轉換為大寫字母,并將當前字節的十六進制字符串形式添加到結果中。
- 輸出結果: 將編碼結果的十六進制字符串形式輸出。
JS題解代碼講解
- 輸入處理: 使用
readline
模塊創建接口實例,監聽line
事件獲取待編碼的非負整數。 - 二進制轉換: 使用
BigInt()
將待編碼數字轉換為二進制字符串。 - 循環編碼: 從二進制字符串的末尾開始,每7位一組進行編碼。
- 將每一組轉換為十六進制字符串,并添加到結果數組中。
- 輸出結果: 將編碼結果數組拼接為一個字符串,并輸出。
寄語
🚀? 朋友,希望你的華為OD機試就像是一場輕松的技術party!愿你的代碼如同暢快的音符,跳躍在鍵盤上,最后彈奏出一曲高分之歌。加油,你是技術舞臺上的巨星!通過機試,就像是風輕云淡,輕輕松松就把高分收入囊中。祝愿你的編程之旅一路順風,破風前行,每一行代碼都是成功的注腳!🌈💻