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

注意:

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

相关推荐
点云SLAM23 分钟前
CVPR 2024 视频处理方向总汇(视频监控、视频理解、视频识别和视频预测等)
python·计算机视觉·音视频·视频监控·视频处理·视频理解
Blasit23 分钟前
Qt C++ QStatusbar 显示表示状态的图片
开发语言·c++·qt
匹马夕阳25 分钟前
基于vite+vue3+mapbox-gl从零搭建一个项目
前端·javascript·vue.js
木心操作27 分钟前
js使用qrcode与canvas生成带logo的二维码
开发语言·javascript·ecmascript
SunkingYang1 小时前
C/C++中,const、static关键字有什么作用,如何定义、初始化,什么情形下需要用到这两关键字?
c语言·c++·const·static·初始化·申明·定义
嵌入式郑工1 小时前
ssh,samba,tftp,nfs服务安装和配置
java·前端·ssh
顽疲3 小时前
从零用java实现 小红书 springboot vue uniapp (10)系统消息模块 接收推送消息优化
java·vue.js·spring boot·uni-app
疯狂的沙粒3 小时前
如何将一个数组转换为字符串?
开发语言·前端·javascript·柔性数组
shix .3 小时前
python范围
开发语言·python
!!!5253 小时前
Mybatis-底层是如何解决sql注入&增删改查操作--删除操作
java·spring boot·mybatis