专栏名称: 吴师兄学算法
和程序员小吴一起从初学者的角度学习算法,以动画的形式呈现解题的思路。每周四篇原创文章,期待你的鉴赏!
51好读  ›  专栏  ›  吴师兄学算法

字节发全员邮件,年终奖大涨

吴师兄学算法  · 公众号  ·  · 2024-12-15 11:30

正文

大家好,我是吴师兄。

最近,字节发了一封全员邮件,调整了年初发布的全年激励方案,尤其是针对高绩效员工的奖励—— 期权更多,年终奖更高

这消息让不少“打工人”兴奋不已,朋友圈一片“沾喜气”的祝福。毕竟,年终奖的大幅上涨,对奋斗一年的职场人来说,无疑是一种认可和鼓励。

年终奖涨了,确实是一件好事,但不妨换个角度想想: 谁能拿到高年终奖?又是谁在被淘汰?

大厂的激励制度,往往不是雨露均沾,而是针对那些掌握核心技能、能直接创造价值的人才。

尤其是在字节这样对技术要求极高的公司, 掌握算法和工程能力的人,永远是赢家

当高绩效员工拿到更多奖励时,那些没有硬核技能、处于边缘岗位的员工,又该如何保证自己的安全感?

正如一句话所说: “危机之中藏着机会,但只有提前准备好的人才能把握住。”

有人可能会觉得,“年终奖的事和我没关系,普通人哪有机会进入大厂?”

但其实,大厂的门并没有想象中那么高不可攀。只要你掌握了一套正确的学习方法和职业规划, 从零开始进入大厂完全不是问题



回归我们公众号的主题, 每天掌握一道算法题

继续来一道和「校招」相关的算法原题。

本原题练习网址:https://www.algomooc.com/problem/K0001

题目描述

小R 负责解析 IP 报文头信息,现有一个十六进制格式的 IP 报文头数据,他需要从中解析并输出其中的 总长度 标志位 以及 目的 IP 地址 ,用逗号分隔。

IP 报文头信息依次包含多个字段,其中标识(16 位)和目的 IP 地址(32 位)是重点。输入数据为合法的十六进制 IP 报文头,固定长度为 59 个字符,每两个十六进制数字表示一个字节,字节之间以单空格分隔。

注:

  • 报文数据为大端序(即高位字节在低地址)。
  • 输出的总长度和标志位为十进制整数,目的 IP 地址为点分十进制格式(如 192.168.20.184 )。

输入描述

第一行输入一个合法的十六进制 IP 报文头字符串 header ,固定长度为 59 个字符,每两个十六进制数字表示一个字节,字节之间以单空格分隔。

  1. header 的长度固定为 59 个字符,且合法。
  2. 所有数据均为大端序。

输出描述

输出一个字符串,包含解析后的总长度、标志位和目的 IP 地址,中间用逗号分隔。

样例

样例1

样例输入:

45 00 10 3c 7c 48 20 03 80 06 00 00 c0 a8 01 02 c0 a8 14 b8

样例输出:

4156,1,192.168.20.184

样例2

样例输入:

4b ba 0d 15 d0 42 16 bc 50 25 38 33 cb e0 77 ed 56 a4 30 46

样例输出:

3349,0,86.164.48.70

样例3

样例输入:

f7 87 78 be cf bf ae 9e d6 bc b1 5f 38 2c 07 37 95 f8 32 c5

样例输出:

30910,5,149.248.50.197

题目解析

这道题要求解析一个固定格式的十六进制 IP 报文头数据,提取出 总长度 标志位 目的 IP 地址 ,并以逗号分隔的字符串形式输出。以下是解析要点:

  1. 输入数据特点
    1. 输入是一个长度为 59 的字符串,每两个字符表示一个字节,以单空格分隔。
    2. 数据采用大端序。
  2. 解析细节
    1. 总长度 :报文头的第 3 和第 4 字节表示总长度,需将其合并为 16 位整数。
    2. 标志位 :报文头的第 7 字节的高 3 位表示标志位,可以通过右移操作提取。
    3. 目的 IP 地址 :报文头的最后 4 个字节表示目的 IP 地址,需将其转换为点分十进制格式。
img
  1. 实现逻辑

    1. 先将输入字符串按空格拆分为每个字节,并转换为十进制整数。
    2. 根据字段位置提取对应数据,并通过位运算和字符串拼接完成转换。
    3. 最终返回所需格式的字符串。
  2. 关键代码解析

ls = list(map(lambda x: int(x, 16), header.split()))  # 将十六进制字符串拆分为整数列表
sz = ls[2] <8 | ls[3]  # 合并第 3 和第 4 字节计算总长度
flag = ls[6] >> 5  # 提取第 7 字节的高 3 位作为标志位
ip = ".".join(map(str, ls[-4:]))  # 将最后 4 个字节转换为点分十进制 IP 地址
  1. 输出结果 :以逗号分隔的字符串格式返回解析结果。

代码

Python

# 本原题练习网址:https://www.algomooc.com/problem/K0001
from typing import List

class Solution:
    def ip_parse(self, header: str) -> str:
        """
        解析十六进制格式的 IP 报文头信息,并提取总长度、标志位和目的 IP 地址。
        
        参数:
            header (str): 十六进制表示的 IP 报文头字符串,每两个字符表示一个字节,字节之间以空格分隔。
            
        返回:
            str: 包含总长度、标志位和目的 IP 地址的字符串,格式为 "总长度,标志位,目的IP地址"。
        """

        # 将输入字符串按空格分割,并将每个十六进制字符串转换为十进制整数,生成一个列表
        ls = list(map(lambda x: int(x, 16), header.split()))
        
        # 第 3 和第 4 字节表示总长度(大端序),合并为一个 16 位整数
        # 左移第 3 字节 8 位,加上第 4 字节的值
        sz = ls[2] <8 | ls[3]
        
        # 第 7 字节的高 3 位表示标志位,通过右移 5 位提取高 3 位
        flag = ls[6] >> 5
        
        # 最后 4 个字节表示目的 IP 地址,将其转换为点分十进制格式
        # 使用 map 将字节转换为字符串,并用 "." 连接
        ip = ".".join(map(str, ls[-4:]))
        
        # 格式化输出,将总长度、标志位和目的 IP 地址用逗号分隔
        return "{},{},{}".format(sz, flag, ip)


if __name__ == '__main__':
    sol = Solution()
    header = input()
    print(sol.ip_parse(header))

不使用任何API的解法(不推荐,圈复杂度过高):

class Solution:
    def src_2_hex_array(self, header):
        # 初始化一个空列表用于存储十六进制值
        hex_values = []
        current = ""  # 用于拼接当前的十六进制字符

        # 遍历输入字符串,将每两个字符分割为一个十六进制数
        for char in header:
            if char != " ":  # 遇到非空格字符,加入当前拼接的字符串
                current += char
            else:  # 遇到空格时,表示一个完整的十六进制数结束
                hex_values.append(current)
                current = ""
        if current:  # 添加最后一个未被空格终止的十六进制数
            hex_values.append(current)
        return hex_values
        
    def hex_array_2_decimal_array(self, hex_values):
        # 将十六进制字符串转换为十进制整数列表
        decimal_values = []
        for hex_value in hex_values:
            decimal_value = 0  # 初始化十进制值
            for char in hex_value:  # 遍历每个十六进制字符
                if '0' <= char <= '9':  # 数字字符处理
                    decimal_value = decimal_value * 16 + (ord(char) - ord('0'))
                else:  # 字母字符处理
                    decimal_value = decimal_value * 16 + (ord(char.lower()) - ord('a') + 10)
            decimal_values.append(decimal_value)
        return decimal_values
        
    def get_ip(self, ip_parts):
        ip = ""  # 用于存储 IP 地址
        for i, part in enumerate(ip_parts):
            ip += str(part)  # 将每个字节转换为字符串
            if i 3:  # 在每个字节之间添加点
                ip += "."
        return ip
        
    def ip_parse(self, header: str) -> str:
        """
        解析十六进制格式的 IP 报文头信息,并提取总长度、标志位和目的 IP 地址。

        参数:
            header (str): 十六进制表示的 IP 报文头字符串,每两个字符表示一个字节,字节之间以空格分隔。






请到「今天看啥」查看全文