HJ33. 整数与IP地址间的转换
题目描述
IP 地址的每一段是一个 0~255 的整数,把四段各自的 8 位二进制拼接成 32 位,再转换为十进制长整数;反之,把十进制长整数拆成四段得到 IP 地址。
输入格式
- 第 1 行:一个 IP 地址(如 10.0.3.193)
- 第 2 行:一个十进制整数
输出格式
- 第 1 行:IP 地址转换成的十进制整数
- 第 2 行:十进制整数转换成的 IP 地址
示例
示例 1
输入:
10.0.3.193
167969729
输出:
167773121
10.3.3.193
解题思路
第一步:理解问题本质
IP 的每段是 8 位二进制,四段拼接成 32 位整数。转换本质是二进制位的左移与拼接、右移与截断。
第二步:暴力解法(字符串拼接二进制)
把每段转成 8 位二进制字符串拼接成 32 位,再用 int(x, 2) 转换;反向则转回二进制按每 8 位切开。
问题:字符串操作繁琐且易错。
第三步:优化解法(位运算)
利用移位与按位或:
- IP → 整数:
int = a<<24 | b<<16 | c<<8 | d - 整数 → IP:依次取高 8 位:
a=(x>>24)&255,b=(x>>16)&255,c=(x>>8)&255,d=x&255
def ip_to_int(ip: str) -> int:
a, b, c, d = map(int, ip.split('.'))
return (a << 24) | (b << 16) | (c << 8) | d
def int_to_ip(x: int) -> str:
return f"{(x >> 24) & 255}.{(x >> 16) & 255}.{(x >> 8) & 255}.{x & 255}"
第四步:最优解法(直接位运算)
位运算一次完成,无需中间字符串,最高效简洁。
完整代码实现
本题无可视化步骤:代码里没有可逐帧展示的过程(执行轨迹已经录下来, 但局部变量里找不到推进中的中间状态 —— 比如全篇就是一次正则替换或一次切片)。
import sys
def ip_to_int(ip: str) -> int:
"""IP 地址 -> 十进制长整数"""
a, b, c, d = map(int, ip.split('.'))
return (a << 24) | (b << 16) | (c << 8) | d
def int_to_ip(x: int) -> str:
"""十进制长整数 -> IP 地址"""
return f"{(x >> 24) & 255}.{(x >> 16) & 255}.{(x >> 8) & 255}.{x & 255}"
def solve() -> None:
"""主求解函数"""
ip = sys.stdin.readline().strip()
num = int(sys.stdin.readline().strip())
print(ip_to_int(ip))
print(int_to_ip(num))
if __name__ == "__main__":
solve()
示例推演
以示例 1 为例:
IP → 整数: 10.0.3.193
- a=10, b=0, c=3, d=193
10<<24 = 167772160,0<<16 = 0,3<<8 = 768,d=193- 拼接:
167772160 | 0 | 768 | 193 = 167773121
整数 → IP: 167969729
a = (167969729>>24) & 255 = 10b = (167969729>>16) & 255 = 3c = (167969729>>8) & 255 = 3d = 167969729 & 255 = 193- 结果:
10.3.3.193
复杂度分析
| 解法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 字符串拼接二进制 | O(1) | O(1) | 需频繁字符串转换 |
| 位运算 | O(1) | O(1) | 一次完成,最简洁 |
易错点总结
1. 移位位数
a 左移 24 位、b 左移 16 位、c 左移 8 位,d 不动,不能混淆。
2. 反向取段用 & 255
整数转 IP 时每段用 & 255 截取低 8 位,右移后再截,否则会混入其他位。
3. 输出顺序
第一行输出 IP 转成的整数,第二行输出整数转成的 IP,顺序不能反。
4. 输入第二行是整数
第二行是一个十进制长整数,可能超过普通 int 的直觉范围但 Python 无此问题。
扩展思考
- IP 与整数的互转是网络编程中的常见操作,位运算是其本质。
& 255等价于对 2^8 取模,>> n等价于整除 2^n,可迁移到其他字节拼接场景。