IPv4地址转换成整数

IPv4地址转换成整数

真题目录: 点击去查看

E 卷 100分题型

题目描述

存在一种虚拟[IPv4地址],由4小节组成,每节的范围为0~255,以#号间隔,虚拟IPv4地址可以转换为一个32位的整数,例如:

  • 128#0#255#255,转换为32位整数的结果为2147549183(0x8000FFFF)

  • 1#0#0#0,转换为32位整数的结果为16777216(0x01000000)

现以字符串形式给出一个虚拟IPv4地址,限制第1小节的范围为1128,即每一节范围分别为(1128)#(0255)#(0255)#(0~255),要求每个IPv4地址只能对应到唯一的整数上。如果是非法IPv4,返回invalid IP

输入描述

输入一行,虚拟IPv4地址格式字符串

输出描述

输出一行,按照要求输出整型或者特定字符

示例1

输入

100#101#1#5

输出

1684340997

示例2

输入

1#2#3

输出

invalid IP

题解

解题思路:

  1. 将输入字符串以#进行分割成一个字符串数组,如果数组长度不为0,代表不合法直接失效。
  2. 遍历检查数组中每个字符串是否合法(只包含数字并且不为空, 是否包含前导零),判断是否为合法IP。
  3. 接下来判断数组中的字符串代表的int数字大小是否符合范围就行。
  4. 进行求和计算,ip地址每一部分相当8位二进制,2^8 = 256

C++实现源码

#include 
#include 
#include 

using namespace std;

// 判断字符串是否为数字
bool isNumeric(const string& str) {
    for (char c : str) {
        if (!isdigit(c)) {
            return false; // 如果有非数字字符则返回false
        }
    }
    return true; // 全部为数字则返回true
}

int main() {
    string input;
    getline(cin, input); // 获取输入的字符串

    // 将输入的字符串按照"#"分割成4个小节
    stringstream ss(input);
    vector ipSections;
    string section;
    while (getline(ss, section, '#')) {
        ipSections.push_back(section);
    }

    if (ipSections.size() != 4) { // 如果分割后的小节数量不等于4,则说明输入的IPv4地址格式不正确
        cout << "invalid IP" << endl;
        return 0; // 结束程序
    }

    // 遍历每个部分进行检查
    for (const string& section : ipSections) {
        if (section.empty() || !isNumeric(section)) { // 检查是否为空或者是否每部分都是数字
            cout << "invalid IP" << endl;
            return 0; // 结束程序
        }

        // 检查前导零的情况
        if (section.length() > 1 && section[0] == '0') {
            cout << "invalid IP" << endl;
            return 0; // 结束程序
        }
    }

    // 检查第一个小节的大小范围 
    int firstSection = stoi(ipSections[0]); // 将第一个小节转换为整数
    if (firstSection < 1 || firstSection > 128) { // 如果第一个小节的值不在1~128的范围内
        cout << "invalid IP" << endl;
        return 0; // 结束程序
    }

    // 检查其余3个小节的范围
    for (int i = 1; i < 4; i++) {
        int sectionValue = stoi(ipSections[i]); // 将当前小节转换为整数
        if (sectionValue < 0 || sectionValue > 255) { // 如果不在0~255范围内
            cout << "invalid IP" << endl;
            return 0; // 结束程序
        }
    }

    // 计算最终的32位整数
    long ipValue = 0;
    for (int i = 0; i < 4; i++) {
        // 也可以使用位运算,计算效率更高 
        //ipValue = ipValue << 8 + stoi(ipSections[i]);
        ipValue = ipValue * 256 + stoi(ipSections[i]); // 每个小节对应一个字节,计算最终的整数值
    }

    cout << ipValue << endl; // 输出最终的32位整数
    return 0;
}

JAVA源码实现

import java.util.*;

public class Main {

    // 判断字符串是否为数字
    private static boolean isNumeric(String str) {
        for (char c : str.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false; // 如果有非数字字符则返回 false
            }
        }
        return true; // 全部为数字则返回 true
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine(); // 获取输入的字符串
        scanner.close();

        // 将输入的字符串按照 "#" 分割成 4 个小节
        String[] ipSections = input.split("#");

        if (ipSections.length != 4) { // 如果分割后的小节数量不等于 4,则说明输入的 IPv4 地址格式不正确
            System.out.println("invalid IP");
            return; // 结束程序
        }

        // 遍历每个部分进行检查
        for (String section : ipSections) {
            if (section.isEmpty() || !isNumeric(section)) { // 检查是否为空或者是否每部分都是数字
                System.out.println("invalid IP");
                return; // 结束程序
            }

            // 检查前导零的情况
            if (section.length() > 1 && section.charAt(0) == '0') {
                System.out.println("invalid IP");
                return; // 结束程序
            }
        }

        // 检查第一个小节的大小范围 
        int firstSection = Integer.parseInt(ipSections[0]); // 将第一个小节转换为整数
        if (firstSection < 1 || firstSection > 128) { // 如果第一个小节的值不在 1~128 的范围内
            System.out.println("invalid IP");
            return; // 结束程序
        }

        // 检查其余 3 个小节的范围
        for (int i = 1; i < 4; i++) {
            int sectionValue = Integer.parseInt(ipSections[i]); // 将当前小节转换为整数
            if (sectionValue < 0 || sectionValue > 255) { // 如果不在 0~255 范围内
                System.out.println("invalid IP");
                return; // 结束程序
            }
        }

        // 计算最终的 32 位整数
        long ipValue = 0;
        for (int i = 0; i < 4; i++) {
            ipValue = ipValue * 256 + Integer.parseInt(ipSections[i]); // 每个小节对应一个字节,计算最终的整数值
        }

        System.out.println(ipValue); // 输出最终的 32 位整数
    }
}

Python实现源码

# def is_numeric(string):
#     """判断字符串是否为数字"""
#     return string.isdigit()

def main():
    # 获取输入的字符串
    input_str = input().strip()

    # 将输入的字符串按照"#"分割成4个小节
    ip_sections = input_str.split('#')

    if len(ip_sections) != 4:  # 如果分割后的小节数量不等于4,则说明输入的IPv4地址格式不正确
        print("invalid IP")
        return

    # 遍历每个部分进行检查
    for section in ip_sections:
        if not section or not section.isdigit():  # 检查是否为空或者是否每部分都是数字
            print("invalid IP")
            return

        # 检查前导零的情况
        if len(section) > 1 and section[0] == '0':
            print("invalid IP")
            return

    # 检查第一个小节的大小范围 
    first_section = int(ip_sections[0])  # 将第一个小节转换为整数
    if first_section < 1 or first_section > 128:  # 如果第一个小节的值不在1~128的范围内
        print("invalid IP")
        return

    # 检查其余3个小节的范围
    for section in ip_sections[1:]:
        section_value = int(section)  # 将当前小节转换为整数
        if section_value < 0 or section_value > 255:  # 如果不在0~255范围内
            print("invalid IP")
            return

    # 计算最终的32位整数
    ip_value = 0
    for section in ip_sections:
        ip_value = ip_value * 256 + int(section)  # 每个小节对应一个字节,计算最终的整数值

    print(ip_value)  # 输出最终的32位整数

if __name__ == "__main__":
    main()

Go实现源码

package main

import (
	"fmt"
	"strconv"
	"strings"
)

// isNumeric 判断字符串是否为数字
func isNumeric(str string) bool {
	for _, c := range str {
		if c < '0' || c > '9' {
			return false
		}
	}
	return true
}

func main() {
	// 获取输入的字符串
	var input string
	fmt.Scanln(&input)
	input = strings.TrimSpace(input)

	// 将输入的字符串按照"#"分割成4个小节
	ipSections := strings.Split(input, "#")

	if len(ipSections) != 4 { // 如果分割后的小节数量不等于4,则说明输入的IPv4地址格式不正确
		fmt.Println("invalid IP")
		return
	}

	// 遍历每个部分进行检查
	for _, section := range ipSections {
		if section == "" || !isNumeric(section) { // 检查是否为空或者是否每部分都是数字
			fmt.Println("invalid IP")
			return
		}

		// 检查前导零的情况
		if len(section) > 1 && section[0] == '0' {
			fmt.Println("invalid IP")
			return
		}
	}

	// 检查第一个小节的大小范围
	firstSection, err := strconv.Atoi(ipSections[0]) // 将第一个小节转换为整数
	if err != nil || firstSection < 1 || firstSection > 128 { // 如果第一个小节的值不在1~128的范围内
		fmt.Println("invalid IP")
		return
	}

	// 检查其余3个小节的范围
	for _, section := range ipSections[1:] {
		sectionValue, err := strconv.Atoi(section) // 将当前小节转换为整数
		if err != nil || sectionValue < 0 || sectionValue > 255 { // 如果不在0~255范围内
			fmt.Println("invalid IP")
			return
		}
	}

	// 计算最终的32位整数
	ipValue := 0
	for _, section := range ipSections {
		sectionValue, _ := strconv.Atoi(section)
		ipValue = ipValue*256 + sectionValue // 每个小节对应一个字节,计算最终的整数值
	}

	fmt.Println(ipValue) // 输出最终的32位整数
}

你可能感兴趣的:(od算法刷题笔记,算法,华为od,笔试真题,数据结构,华为od,E卷真题)