【华为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)#(0255)#(0255)#(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”,否则返回计算结果
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 # 分段数量必须为 4not 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”。
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("#");// 验证分割后的段数是否为 4if (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 位整数(无符号表示),并输出结果。
#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解法
更新中
JS解法
-
解题思路
-
这段代码的目标是将一个以 # 分隔的自定义格式 IP 地址(例如 10#200#30#40)转换为整数。如果输入的 IP 地址格式或内容不合法,返回 “invalid IP”。具体步骤如下:
分割字符串:使用 # 分隔输入字符串,得到 4 个片段。
验证分段数量:确保分割后的数组长度为 4。
验证每段的合法性:
每段必须是数字。
第一段范围为 [1, 128]。
其他段范围为 [0, 255]。
计算整数结果:
使用位操作将每段值拼接为一个 32 位整数:
第一段左移 24 位,第二段左移 16 位,第三段左移 8 位,第四段保持不变。
返回结果:
如果验证失败,返回 “invalid IP”。
如果验证通过,返回计算的整数。
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("#"); // 按 "#" 分割输入字符串// 检查分割后的部分数量是否为 4if (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";}// 初始化结果为 0let 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) // 检查是否为整数);
}
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏