#P3052. IPv4地址转换成整数(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 158
            Accepted: 51
            Difficulty: 2
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>模拟          
 
IPv4地址转换成整数(100分)
题目描述
给定一个由 # 分隔的虚拟IPv4地址字符串,地址由4个部分组成:
- 第1部分:范围为1~128
 - 第2至第4部分:范围为0~255
 
要求将合法的虚拟IPv4地址转换为一个32位整数输出。如果输入的地址不合法,则输出 invalid IP。
解题思路
- 字符串分割:使用分隔符 
#将输入字符串分割成4个部分。 - 合法性校验:
- 部分数量:检查分割后的部分数量是否为4。
 - 字符检查:确保每个部分只包含数字字符。
 - 数值范围:验证每个部分的数值是否在指定范围内。
 
 - 整数转换:将每个部分按照IP地址的规则,组合成一个32位整数。
- 位移运算:使用位移和位或运算将各部分合并。
 
 - 异常处理:在任何一步发现不合法的情况,立即输出 
invalid IP。 
cpp
#include <iostream>
#include <sstream>
#include <vector>
#include <cctype>
using namespace std;
// 判断字符串是否为纯数字
bool isNumber(const string& s) {
    if (s.empty()) return false; // 空字符串不合法
    for (char c : s) {
        if (!isdigit(c)) return false; // 非数字字符不合法
    }
    return true;
}
int main() {
    string input;
    getline(cin, input); // 读取整行输入
    vector<string> parts;
    stringstream ss(input);
    string part;
    // 按 '#' 分割字符串
    while (getline(ss, part, '#')) {
        parts.push_back(part);
    }
    if (parts.size() != 4) {
        cout << "invalid IP" << endl; // 部分数量不为4,非法
        return 0;
    }
    // 定义每个部分的合法范围
    int ranges[4][2] = {{1, 128}, {0, 255}, {0, 255}, {0, 255}};
    unsigned int result = 0;
    for (int i = 0; i < 4; ++i) {
        if (!isNumber(parts[i])) {
            cout << "invalid IP" << endl; // 非数字字符,非法
            return 0;
        }
        int num = stoi(parts[i]); // 将字符串转换为整数
        if (num < ranges[i][0] || num > ranges[i][1]) {
            cout << "invalid IP" << endl; // 数值不在合法范围内,非法
            return 0;
        }
        result = (result << 8) | num; // 位移并合并到结果中
    }
    cout << result << endl; // 输出结果
    return 0;
}
python
import sys
# 判断字符串是否为纯数字
def is_number(s):
    return s.isdigit()
def main():
    input_str = sys.stdin.readline().strip() # 读取并去除换行符
    parts = input_str.split('#') # 按 '#' 分割字符串
    if len(parts) != 4:
        print("invalid IP") # 部分数量不为4,非法
        return
    ranges = [(1, 128), (0, 255), (0, 255), (0, 255)] # 定义每个部分的合法范围
    result = 0
    for i in range(4):
        part = parts[i]
        if not is_number(part):
            print("invalid IP") # 非数字字符,非法
            return
        num = int(part)
        if num < ranges[i][0] or num > ranges[i][1]:
            print("invalid IP") # 数值不在合法范围内,非法
            return
        result = (result << 8) | num # 位移并合并到结果中
    print(result) # 输出结果
if __name__ == "__main__":
    main()
java
import java.util.Scanner;
public class Main {
    // 判断字符串是否为纯数字
    public static boolean isNumber(String s) {
        if (s.isEmpty()) return false; // 空字符串不合法
        for (char c : s.toCharArray()) {
            if (!Character.isDigit(c)) return false; // 非数字字符不合法
        }
        return true;
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine(); // 读取整行输入
        String[] parts = input.split("#"); // 按 '#' 分割字符串
        if (parts.length != 4) {
            System.out.println("invalid IP"); // 部分数量不为4,非法
            return;
        }
        int[][] ranges = {{1, 128}, {0, 255}, {0, 255}, {0, 255}}; // 定义每个部分的合法范围
        long result = 0; // 使用 long 避免溢出
        for (int i = 0; i < 4; i++) {
            String part = parts[i];
            if (!isNumber(part)) {
                System.out.println("invalid IP"); // 非数字字符,非法
                return;
            }
            int num = Integer.parseInt(part);
            if (num < ranges[i][0] || num > ranges[i][1]) {
                System.out.println("invalid IP"); // 数值不在合法范围内,非法
                return;
            }
            result = (result << 8) | num; // 位移并合并到结果中
        }
        System.out.println(result); // 输出结果
    }
}
        题目描述
存在一种虚拟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,返回 invalidIP
输入描述
输入一行,虚拟IPv4地址格式字符串
输出描述
输出一行,按照要求输出整型或者特定字符
备注
输入不能确保是合法的IPv4地址,需要对非法IPv4(空串,含有IP地址中不存在的字符,非合法的#分十进制,十进制整数不在合法区间内)进行识别,返回特定错误
样例1
输入
100#101#1#5
输出
1684340997
样例2
输入
1#2#3
输出
invalid IP