【华为OD-E卷 - 整数编码 100分(python、java、c++、js、c)】

news/2025/1/15 11:07:14/

pythonjavacjsc_0">【华为OD-E卷 - 整数编码 100分(pythonjava、c++、js、c)】

题目

实现一种整数编码方法,使得待编码的数字越小,编码后所占用的字节数越小。
编码规则如下:
编码时7位一组,每个字节的低7位用于存储待编码数字的补码 字节的最高位表示后续是否还有字节,置1表示后面还有更多的字节,置0表示当前字节为最后一个字节。 采用小端序编码,低位和低字节放在低地址上。 编码结果按16进制数的字符格式输出,小写字母需转换为大写字母

输入描述

  • 输入的为一个字符串表示的非负整数

输出描述

  • 输出一个字符串,表示整数编码的16进制码流

备注

  • 待编码的数字取值范围为[0,1<<64 - 1]

用例

用例一:
输入:
0
输出:
00
用例二:
输入:
100
输出:
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输出在后。

python_73">python解法

  • 解题思路:
  • 该问题是将一个整数编码为变长的字节序列,其中每个字节的最高位是一个标志位,表示后续字节是否存在。具体来说,使用7位来表示数值,剩余的1位用作标志位来表示是否还有后续字节。每次编码后,若数值还大于等于128(即7位无法完全表示),则需要继续编码。最终返回的结果是这些字节的十六进制表示。

对于每个数值,取低7位作为当前字节的值(通过与0x7F按位与操作获得),然后将这个字节的最高位设为1(通过按位或操作),表示后续还有字节。
当数值变小到小于128时,停止编码,将其直接以十六进制格式返回

python">def encode_number(num):res = []  # 用于保存每个编码后的字节while num >= 128:  # 当数字大于等于128时,需要继续编码# 通过num & 0x7F 获取低7位,0x80表示设置字节的最高位为1res.append(f"{(num & 0x7F) | 0x80:02X}")  # 格式化为2位的十六进制数,添加到结果列表num >>= 7  # 将num右移7位,为编码下一段数值做准备# 最后一个字节,直接以低7位表示,无需设置最高位res.append(f"{num:02X}")  # 格式化为2位的十六进制数,添加到结果列表return "".join(res)  # 将所有字节拼接成一个字符串并返回# 输入整数,进行编码并输出结果
num = int(input())  # 从用户输入读取一个整数
print(encode_number(num))  # 调用encode_number函数进行编码,并打印结果

java_98">java解法

  • 解题思路
  • 该问题是将一个 long 类型的整数编码为变长的字节序列,其中每个字节的最高位是一个标志位,用来表示是否还有后续字节。每个字节的低7位用来表示数值的部分。根据编码规则,处理的过程如下:

每个字节的构成:
对于一个整数,将其分解为多个字节。每个字节表示 7 位数值,最高位(即第8位)用作标志位,表示后续是否还有字节。如果某个字节的最高位是 1,说明后面还有字节。如果是 0,表示这是最后一个字节。

过程:

将整数按 7 位拆分。
对于每个拆分出来的部分,设置其最高位为 1(表示后面还有字节)直到没有更多的数值需要编码。
当数值小于 128 时,设置该字节的最高位为 0,表示这是最后一个字节。
通过按位操作,逐步提取每个字节,并拼接结果。
编码输出:
编码后的结果是一个十六进制的字符串,表示每个字节

java">import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);  // 创建Scanner对象用于读取输入long val = in.nextLong();  // 读取一个long类型的数值Encoder enc = new Encoder();  // 创建Encoder对象System.out.println(enc.encode(val));  // 调用Encoder的encode方法,输出编码结果}
}class Encoder {// 编码方法:将long类型的val编码为变长字节序列public String encode(long val) {StringBuilder sb = new StringBuilder();  // 用于构建编码后的字符串boolean cont = true;  // 标志位,表示是否还需要继续编码// 当还需要继续编码时while (cont) {// 获取val的低7位,使用int类型保存,低7位用来表示字节的内容int num = (int) (val & 0x7F);val >>>= 7;  // 无符号右移7位,为下一次编码做准备// 如果val还有剩余的数值,则设置当前字节的最高位为1if (val != 0) {num |= 0x80;  // 设置最高位为1,表示后续还有字节} else {cont = false;  // 如果val已经处理完,停止编码}// 将当前字节num以2位大写十六进制格式添加到StringBuilder中sb.append(String.format("%02X", num));}return sb.toString();  // 返回编码后的十六进制字符串}
}

C++解法

  • 解题思路
  • 该问题的目标是将一个给定的 long long 类型整数编码成一个变长字节流,每个字节由7位数据和1位标志位组成。具体规则是:

字节格式:每个字节的最低7位用来存储数据,而最高1位用来作为标志位,表示是否还有后续字节。如果最高位为 1,表示还有更多字节;如果为 0,表示没有后续字节。
拆分流程:
将整数转换为二进制字符串。
按照每7位一组将其拆分。
对每一组数据,若不为最后一组,则设置最高位为 1,表示后续还有字节;否则,设置为 0,表示结束。
结果表示:将每个字节转为十六进制字符串,并拼接成最终的编码结果

#include <iostream>
#include <string>
#include <bitset>
#include <sstream>
#include <iomanip>using namespace std;// 将二进制字符串转换为十六进制字符串
string getHexString(const string &binStr) {int hexValue = stoi(binStr, nullptr, 2);  // 将二进制字符串转换为十进制整数stringstream ss;  // 创建字符串流// 将整数输出为十六进制格式,宽度为2,若不足两位前补零,且使用大写字母ss << hex << uppercase << setw(2) << setfill('0') << hexValue;return ss.str();  // 返回转换后的十六进制字符串
}// 获取结果,将long long类型的num转换为变长编码的十六进制字符串
string getResult(long long num) {// 将num转换为64位的二进制字符串string bin = bitset<64>(num).to_string();// 去掉二进制字符串前面的0,保留有效的二进制部分bin = bin.substr(bin.find('1')); stringstream ans;  // 用于保存编码后的十六进制结果int end = bin.length();  // 获取二进制字符串的长度// 按7位一组地处理二进制字符串while (end - 7 > 0) {// 获取当前的7位数据,并在其前面加上1,表示后面还有数据ans << getHexString("1" + bin.substr(end - 7, 7));  end -= 7;  // 更新剩余处理的二进制数据长度}// 处理最后不足7位的二进制数据if (end > 0) {ans << getHexString(bin.substr(0, end));  // 最后一个字节无需添加最高位的1}return ans.str();  // 返回编码后的十六进制字符串
}int main() {long long num;  // 定义long long类型的输入cin >> num;  // 读取输入的数字cout << getResult(num) << endl;  // 调用getResult函数并输出结果return 0;
}

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 这个问题是将一个大整数(通过字符串输入)编码为变长字节流,并返回其十六进制表示。每个字节包含7位数据和1位标志位。每个字节的标志位(最高位)用来指示是否还有后续字节,规则如下:

字节构成:

每个字节包含 7 位数据(低7位)和 1 位标志位(最高位)。
若当前字节的标志位为 1,表示后续还有字节需要编码;若为 0,表示当前字节是最后一个字节。
编码过程:

将输入的整数转为 BigInt 类型(处理大整数)。
使用 while 循环按 7 位拆分整数,并为每个字节设置标志位。
将所有字节转换为十六进制,并拼接成最终的结果。
输出:

返回变长编码的十六进制字符串,确保每个字节都以两位十六进制表示(不足两位前补零)

javascript">const readline = require("readline");  // 引入 readline 模块用于读取标准输入// 创建 readline 接口
const rl = readline.createInterface({input: process.stdin,  // 从标准输入读取output: process.stdout,  // 输出到标准输出
});// 监听每一行输入
rl.on("line", (line) => {console.log(encodeNumber(line));  // 每输入一行,调用encodeNumber进行编码并打印输出
});// 编码函数:将输入的数字(字符串形式)编码为变长字节流的十六进制字符串
function encodeNumber(numStr) {let num = BigInt(numStr);  // 将输入的字符串转为 BigInt 类型,支持大整数const result = [];  // 用于存储每个字节(编码后的字节)// 循环处理每个字节while (num > 0) {let byte = Number(num & 0x7Fn);  // 获取 num 的最低7位(即低7位),并将其转换为普通数字num >>= 7n;  // 将 num 右移 7 位,准备处理下一部分数据if (num > 0) {byte |= 0x80;  // 如果 num 仍然大于 0,说明后续还有字节,设置当前字节的最高位为1}result.push(byte);  // 将当前字节加入结果数组}// 处理 num 为 0 的情况if (result.length === 0) {result.push(0);  // 如果输入是0,结果数组中应该只有一个字节,值为0}// 将每个字节转换为十六进制字符串,并拼接成最终的结果return result.map(byte => byte.toString(16).padStart(2, '0').toUpperCase()).join("");
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏


http://www.ppmy.cn/news/1563301.html

相关文章

安全测评主要标准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 安全测评的主要标准‌包括多个国际和国内的标准&#xff0c;这些标准为信息系统和产品的安全评估提供了基础和指导。 一、安全测评的主要标准 1.1、国际标准 ‌可信计算机系统评估准则&#xff08;TC…

【微服务】面试题 5、分布式系统理论:CAP 与 BASE 详解

分布式系统理论&#xff1a;CAP 与 BASE 详解 一、CAP 定理 背景与定义&#xff1a;1998 年由加州大学科学家埃里克布鲁尔提出&#xff0c;分布式系统存在一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容错性&#xff08;Part…

精通Python (10)

一&#xff0c;基于tkinter模块的GUI GUI是图形用户界面的缩写&#xff0c;图形化的用户界面对使用过计算机的人来说应该都不陌生&#xff0c;在此也无需进行赘述。Python默认的GUI开发模块是tkinter&#xff08;在Python 3以前的版本中名为Tkinter&#xff09;&#xff0c;从这…

1. Doris分布式环境搭建

一. 环境准备 本次测试集群采用3台机器hadoop1、hadoop2、hadoop3, Frontend和Backend部署在同一台机器上&#xff0c;Frontend部署3台组成高可用&#xff0c;Backend部署3个节点&#xff0c;组成3副本存储。 主机IP操作系统FrontendBackendhadoop1192.168.47.128Centos7Foll…

C++实现设计模式---原型模式 (Prototype)

原型模式 (Prototype) 原型模式 是一种创建型设计模式&#xff0c;它通过复制现有对象来创建新对象&#xff0c;而不是通过实例化。 意图 使用原型实例指定要创建的对象类型&#xff0c;并通过复制该原型来生成新对象。提供一种高效创建对象的方式&#xff0c;尤其是当对象的…

初阶数据结构【双链表及其接口的实现】

目录 前言一、基本结构二、双链表的接口实现2.1 双链表基本功能接口2.1.1 双向链表打印2.1.2 申请一个节点2.1.3 创建并返回双向链表的头结点2.1.4 双向链表清理&#xff08;不销毁&#xff09;2.1.5 双向链表销毁 2.2 双向链表增加节点接口2.2.1 双向链表头插2.2.2 双向链表尾…

如何选择 Redis 持久化方式?RDB 和 AOF 的优缺点分析

前言 在开发中&#xff0c;Redis 通常作为缓存使用。由于其特性&#xff0c;查询数据通常比直接访问关系型数据库快得多。但如果未开启持久化&#xff0c;内存中的缓存可能会因意外丢失&#xff0c;尤其是还未同步到持久层的数据。这让持久化变得非常重要。本文将分享我对 Redi…

jupyter notebook练手项目:线性回归——学习时间与成绩的关系

线性回归——学习时间与学习成绩的关系 第1步&#xff1a;导入工具库 pandas——数据分析库&#xff0c;提供了数据结构&#xff08;如DataFrame和Series&#xff09;和数据操作方法&#xff0c;方便对数据集进行读取、清洗、转换等操作。 matplotlib——绘图库&#xff0c;p…