【华为OD-E卷 - IPv4地址转换成整数 100分(python、java、c++、js、c)】
题目
存在一种虚拟IPv4地址,由4小节组成,每节的范围为0~255,以#号间隔,虚拟IPv4地址可以转换为一个32位的整数,例如:
128#0#255#255,转换为32位整数的结果为2147549183(0x8000FFFF) 1#0#0#0,转换为32位整数的结果为16777216(0x01000000) 现以字符串形式给出一个虚拟IPv4地址,限制第1小节的范围为1 ~ 128,即每一节范围分别为(1 ~ 128)#(0~255)#(0~255)#(0~255),要求每个IPv4地址只能对应到唯一的整数上。
如果是非法IPv4,返回invalid IP
输入描述
- 输入一行,虚拟IPv4地址格式字符串
输出描述
- 输出一行,按照要求输出整型或者特定字符
备注
- 输入不能确保是合法的IPv4地址,需要对非法IPv4(空串,含有IP地址中不存在的字符,非合法的#分十进制,十进制整数不在合法区间内)进行识别,返回特定错误
用例
用例一:
输入:
100#101#1#5
输出:
1684340997
用例二:
输入:
1#2#3
输出:
invalid IP
python解法
- 解题思路:
- 这段代码的目的是验证输入是否是一个合法的自定义格式 IP 地址,并将其转换为一个十进制整数。输入的 IP 地址格式为:a#b#c#d,其中:
a 的范围是 [1, 128]。
b, c, d 的范围是 [0, 255]。
主要分为以下步骤:
拆分输入字符串:根据 # 分隔符将输入分割成 4 个部分。
验证每个部分:确保每个部分是一个合法的数字,并且在指定的范围内。
转换为十六进制:将每部分的十进制数字转换为 2 位十六进制字符串。
拼接和转换:拼接所有十六进制字符串并将其转换为十进制整数。
返回结果:如果输入不符合格式,返回 "invalid IP",否则返回计算结果
python
addr = input() # 输入一个自定义格式的 IP 地址
# 将十进制数转换为 2 位十六进制字符串
def toHex(p):
x = hex(int(p))[2:] # 将数字转换为十六进制,并去掉前缀 '0x'
return x.zfill(2) # 确保结果为 2 位,前面补 0
# 检查字符串是否为合法的数字,并且在指定范围内
def check(a, min_val, max_val):
try:
n = int(a) # 尝试将字符串转换为整数
return str(n) == a and min_val <= n <= max_val # 检查范围并确保输入无多余字符
except:
return False # 如果转换失败,返回 False
# 处理输入 IP 地址并返回结果
def process():
# 按 '#' 分割输入字符串
segs = addr.split("#")
# 验证分段数量和每段是否符合要求
if (len(segs) != 4 or # 分段数量必须为 4
not check(segs[0], 1, 128) or # 第 1 段的范围为 [1, 128]
not check(segs[1], 0, 255) or # 第 2 段的范围为 [0, 255]
not check(segs[2], 0, 255) or # 第 3 段的范围为 [0, 255]
not check(segs[3], 0, 255)): # 第 4 段的范围为 [0, 255]
return "invalid IP" # 如果验证失败,返回无效 IP 信息
# 转换每段为 2 位十六进制字符串,并拼接成完整的十六进制表示
hex_value = toHex(segs[0]) + toHex(segs[1]) + toHex(segs[2]) + toHex(segs[3])
# 将十六进制字符串转换为十进制整数并返回
return str(int(hex_value, 16))
# 输出最终结果
print(process())
java解法
- 解题思路
- 这段 Java 代码的目标是将一个以 # 分隔的自定义格式 IP 地址(例如 10#200#30#40)转换为一个整数。如果输入的 IP 地址格式或内容不合法,返回 "invalid IP"。具体步骤如下:
分割字符串:使用 # 作为分隔符,将输入字符串分割成 4 段。
验证分段长度:确保分割后正好有 4 段。
解析和验证每段:
将每段解析为整数。
验证每段是否在指定的范围内:
第一段范围是 [1, 128]。
其他段范围是 [0, 255]。
计算结果:
使用位操作将 4 段的整数值转换为一个 32 位的无符号整数。
通过位移和按位或(|)操作将每段拼接到结果中:
第一段左移 24 位,第二段左移 16 位,第三段左移 8 位,第四段保持不变。
返回结果:如果所有验证通过,返回计算结果;否则返回 "invalid IP"。
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建 Scanner 对象读取输入
String ipAddress = scanner.nextLine(); // 读取用户输入
System.out.println(convertToInteger(ipAddress)); // 调用方法并输出结果
}
// 将自定义格式 IP 地址转换为整数
public static String convertToInteger(String address) {
// 按 "#" 分割输入字符串
String[] parts = address.split("#");
// 验证分割后的段数是否为 4
if (parts.length != 4) return "invalid IP";
try {
// 解析每一段为整数
int part1 = Integer.parseInt(parts[0]);
int part2 = Integer.parseInt(parts[1]);
int part3 = Integer.parseInt(parts[2]);
int part4 = Integer.parseInt(parts[3]);
// 验证每一段的范围是否符合要求
if (part1 < 1 || part1 > 128 || // 第一段范围为 [1, 128]
part2 < 0 || part2 > 255 || // 第二段范围为 [0, 255]
part3 < 0 || part3 > 255 || // 第三段范围为 [0, 255]
part4 < 0 || part4 > 255) { // 第四段范围为 [0, 255]
return "invalid IP"; // 如果任何一段不符合范围,返回 "invalid IP"
}
// 使用位移操作将每段转换为一个 32 位整数
long result = (long) part1 << 24 | // 第一段左移 24 位
(long) part2 << 16 | // 第二段左移 16 位
(long) part3 << 8 | // 第三段左移 8 位
part4; // 第四段保持不变
// 返回计算结果
return String.valueOf(result);
} catch (NumberFormatException e) {
// 如果字符串不能转换为整数,捕获异常并返回 "invalid IP"
return "invalid IP";
}
}
}
C++解法
- 解题思路
- 这段代码的目标是将一个自定义格式的 IP 地址(例如 10#200#30#40)转换为一个整数。输入的 IP 地址需要满足以下条件:
必须由 # 分割成 4 个部分。
第一部分的数值范围为 [1, 128]。
其余三部分的数值范围为 [0, 255]。
如果输入不符合上述条件,程序返回 "invalid IP";如果符合条件,将其转换为一个 32 位整数(无符号表示),并输出结果。
cpp
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
// 将自定义格式的 IP 地址转换为整数
string convertToInteger(const string& address) {
stringstream ss(address); // 使用 stringstream 分割字符串
string segment; // 存储每次分割后的片段
vector<int> parts; // 存储分割后的整数部分
// 分割地址
while (getline(ss, segment, '#')) { // 按 '#' 分割字符串
try {
parts.push_back(stoi(segment)); // 将每个部分转换为整数并存储到 parts 中
} catch (exception& e) {
return "invalid IP"; // 如果转换失败,返回 "invalid IP"
}
}
// 检查是否有 4 个部分
if (parts.size() != 4) {
return "invalid IP"; // 如果分割部分不是 4 段,返回 "invalid IP"
}
// 验证各个部分的范围
for (int i = 0; i < 4; ++i) {
if (i == 0 && (parts[i] < 1 || parts[i] > 128)) { // 第一部分的范围是 [1, 128]
return "invalid IP";
}
if (i > 0 && (parts[i] < 0 || parts[i] > 255)) { // 后三部分的范围是 [0, 255]
return "invalid IP";
}
}
// 将 IP 地址转换为一个整数
long long result = static_cast<long long>(parts[0]) << 24 | // 第一部分左移 24 位
static_cast<long long>(parts[1]) << 16 | // 第二部分左移 16 位
static_cast<long long>(parts[2]) << 8 | // 第三部分左移 8 位
parts[3]; // 第四部分保留原位
return to_string(result); // 返回结果的字符串形式
}
int main() {
string ipAddress;
getline(cin, ipAddress); // 从用户输入读取自定义 IP 地址
cout << convertToInteger(ipAddress) << endl; // 输出转换结果
return 0;
}
C解法
解题思路
c
更新中
JS解法
解题思路
- 这段代码的目标是将一个以 # 分隔的自定义格式 IP 地址(例如 10#200#30#40)转换为整数。如果输入的 IP 地址格式或内容不合法,返回 "invalid IP"。具体步骤如下:
分割字符串:使用 # 分隔输入字符串,得到 4 个片段。
验证分段数量:确保分割后的数组长度为 4。
验证每段的合法性:
每段必须是数字。
第一段范围为 [1, 128]。
其他段范围为 [0, 255]。
计算整数结果:
使用位操作将每段值拼接为一个 32 位整数:
第一段左移 24 位,第二段左移 16 位,第三段左移 8 位,第四段保持不变。
返回结果:
如果验证失败,返回 "invalid IP"。
如果验证通过,返回计算的整数。
javascript
const readline = require("readline");
// 创建 readline 接口,用于从标准输入读取数据
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// 监听用户输入,每次输入都会调用回调函数
rl.on("line", (input) => {
console.log(convertToInteger(input)); // 调用转换函数并输出结果
});
// 将自定义 IP 地址转换为整数
function convertToInteger(ipStr) {
const segments = ipStr.split("#"); // 按 "#" 分割输入字符串
// 检查分割后的部分数量是否为 4
if (segments.length !== 4) {
return "invalid IP";
}
// 验证每段的合法性
if (
!segments.every((seg, index) =>
validateSegment(seg, index === 0 ? 1 : 0, 255) // 第一段的范围为 [1, 128],其他段为 [0, 255]
)
) {
return "invalid IP";
}
// 初始化结果为 0
let result = 0;
for (let i = 0; i < 4; i++) {
// 将每段数字左移相应位数,并使用按位或 "|" 合并到结果中
result |= parseInt(segments[i]) << ((3 - i) * 8);
}
return result; // 返回最终计算结果
}
// 验证单个段是否合法
function validateSegment(segment, min, max) {
const num = Number(segment); // 将字符串转换为数字
return (
!isNaN(num) && // 检查是否为有效数字
String(num) === segment && // 确保字符串为纯数字,没有多余字符
num >= min && // 检查是否大于等于最小值
num <= max && // 检查是否小于等于最大值
Number.isInteger(num) // 检查是否为整数
);
}
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏