【华为OD-E卷 - IPv4地址转换成整数 100分(python、java、c++、js、c)】

【华为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",否则返回计算结果

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) // 检查是否为整数
  );
}

注意:

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

相关推荐
Tanecious.32 分钟前
机器视觉--python基础语法
开发语言·python
ALe要立志成为web糕手41 分钟前
SESSION_UPLOAD_PROGRESS 的利用
python·web安全·网络安全·ctf
战族狼魂1 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
TDengine (老段)2 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
Tttian6222 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
xyliiiiiL2 小时前
ZGC初步了解
java·jvm·算法
杉之3 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
蹦蹦跳跳真可爱5893 小时前
Python----机器学习(KNN:使用数学方法实现KNN)
人工智能·python·机器学习
再学一点就睡3 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
Merokes3 小时前
关于Gstreamer+MPP硬件加速推流问题:视频输入video0被占用
c++·音视频·rk3588