可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳od1441
了解算法冲刺训练(备注【CSDN】否则不通过)
从2024年8月14号开始,OD机考全部配置为2024E卷。
注意几个关键点:
存在一种虚拟IPv4地址,由4
小节组成,除了第一小节的范围是1-128
以外,其余三节的范围为0-255
,以#
号间隔,格式如下:
(1~128)#(0~255)#(0~255)#(0~255)
例如:
128#0#255#255`,转换为`32`位整数的结果为`2147549183(0x8000ffff)
1#0#0#0`,转换为`32`位整数的结果为`16777216(0x01000000)
请利用这个特性把虚拟IPv4地址转换为一个32
位的整数,IPv4地址以字符串形式给出,要求每个IPvV4地址只能对应到唯一的整数上。
如果是非法IPv4,输出字符串"invalid IP"
。
输入一行,虚拟IPv4地址格式字符串
输出一行,按照要求输出整型或者特定字符
输入不能确保是合法的IPv4地址,需要对非法IPv4 (空串,含有IP地址中不存在的字符,非合法的#
分十进制,十进制整数不在合法区间内)进行识别,返回特定错误。
100#101#1#5
1684340997
1#2#3
invalid IP
对于输入的原字符串s
,我们可以很方便地使用split()
方法,以"#"
为分隔符,将其分割为一个字符串列表IPv4_lst
。然后对IPv4_lst
考虑以下特殊情况:
IPv4_lst
长度不为4
IPv4_lst
中存在某一个字符串,不是纯数字IPv4_lst[0]
即第一小节的取值范围不是1-128
IPv4_lst[1]
、IPv4_lst[2]
、IPv4_lst[3]
即第二、三、四小节的取值范围不是0-255
如果满足以上任何一种情况,输入均是一个非法字符,应该输出"invalid IP"
。
对于一个合法的输入,我们需要理解将IPv4地址转换为整数是一个怎么样的过程,再将抽象的过程翻译成代码即可。属于一道非常纯粹的模拟题。
以128#0#255#255
转为2147549183(0x8000ffff)
为例,其过程如下:
#
为分隔符,将原输入字符串分割为四个小节,为4
个十进制数整数,即IPv4_lst = ["128", "0", "255", "255"]
IPv4_lst = input().split("#")
["80", "00", "ff", "ff"]
255 = 16 * 16 - 1
,等于十六进制的"ff"
,最多为两位。hex()
内置函数对原十进制数进行转换,将得到一个形如"0xFF"
的字符串,其中前缀"0x"
表示这是一个十六进制数。在这里需要使用切片对"0x"
进行去除。16
,那么转换后的数字位数为1
,需要在前面补一个"0"
,才能使得其十六进制数的位数保持为2
。譬如十进制的15
,其十六进制为"f"
,位数为1
位,需要在前面补一个"0"
将其变成"0f"
。IPv4_lst_16base = [hex(int(num)) for num in IPv4_lst]
IPv4_lst_16base = [item[2:] for item in IPv4_lst_16base]
IPv4_lst_16base = list(map(lambda x: "0" * (2-len(x))+x, IPv4_lst_16base))
4
个两位的十六进制整数进行拼接,得到一个八位的十六进制数"8000FFFF"
IPv4_str_16base = "".join(IPv4_lst_16base)
2147549183
ans = int(IPv4_str_16base, base = 16)
# 题目:2024E-IPv4地址转换成整数
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:模拟/进制转换
# 代码看不懂的地方,请直接在群上提问
# 将输入的字符串,以"#"为分隔符进行分割
# 得到一个长度为4的字符串数组IPv4_lst
IPv4_lst = input().split("#")
# 设置标记isError,初始化为False表示没有出现错误
isError = False
# 一些特殊情况的判断
# 如果IPv4_lst长度不为4,出现错误
if len(IPv4_lst) != 4:
isError = True
# 如果IPv4_lst中包含不是数字的字符串,出现错误
elif not all(num.isdigit() for num in IPv4_lst):
isError = True
# 第一小节的取值范围是1-128,如果不落在这个范围内,出现错误
elif int(IPv4_lst[0]) > 128 or int(IPv4_lst[0]) == 0:
isError = True
# 第二、三、四小节的取值范围是0-255,如果不落在这个范围内,出现错误
elif not all(0 <= int(num) <= 255 for num in IPv4_lst[1:]):
isError = True
# 剩余情况,才是符合要求的,可以做进制转换的字符串
else:
# 将IPv4_lst中的十进制整数转化为10进制数,使用内置函数hex()
IPv4_lst_16base = [hex(int(num)) for num in IPv4_lst]
# 转换后每一个十六进制的字符串都会存在一个"0x"前缀,故要用切片操作进行去除
IPv4_lst_16base = [item[2:] for item in IPv4_lst_16base]
# 每一个十六进制数,长度必须是2,故不够2位的需要在前面补0,补齐成2位
# 如十六进制的"5"需要改成"05"
IPv4_lst_16base = list(map(lambda x: "0" * (2-len(x))+x, IPv4_lst_16base))
# 将4个十六进制数合并成一个长度为8的字符串
IPv4_str_16base = "".join(IPv4_lst_16base)
# 将IPv4_str_16base转化为十进制数,使用内置函数int()
ans = int(IPv4_str_16base, base = 16)
# 输出答案
print(ans)
if isError:
print("invalid IP")
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
scanner.close();
String[] IPv4_lst = input.split("#");
boolean isError = false;
if (IPv4_lst.length != 4) {
isError = true;
} else if (!isAllDigits(IPv4_lst)) {
isError = true;
} else if (Long.parseLong(IPv4_lst[0]) > 128 || Long.parseLong(IPv4_lst[0]) == 0) {
isError = true;
} else if (!isInRange(IPv4_lst, 1, 3)) {
isError = true;
} else {
StringBuilder IPv4_str_16base = new StringBuilder();
for (String num : IPv4_lst) {
String hexNum = Long.toHexString(Long.parseLong(num));
if (hexNum.length() < 2) {
hexNum = "0" + hexNum;
}
IPv4_str_16base.append(hexNum);
}
long ans = Long.parseLong(IPv4_str_16base.toString(), 16);
System.out.println(ans);
}
if (isError) {
System.out.println("invalid IP");
}
}
private static boolean isAllDigits(String[] arr) {
for (String num : arr) {
if (!num.matches("\\d+")) {
return false;
}
}
return true;
}
private static boolean isInRange(String[] arr, int start, int end) {
for (int i = start; i <= end; i++) {
long num = Long.parseLong(arr[i]);
if (num < 0 || num > 255) {
return false;
}
}
return true;
}
}
#include
#include
#include
using namespace std;
bool areAllDigits(const vector<string>& arr) {
for (const string& num : arr) {
for (char c : num) {
if (!isdigit(c)) {
return false;
}
}
}
return true;
}
bool areAllInRange(const vector<string>& arr, long start, long end) {
for (long i = start; i <= end; i++) {
long num = stol(arr[i]);
if (num < 0 || num > 255) {
return false;
}
}
return true;
}
int main() {
string input;
getline(cin, input);
stringstream ss(input);
vector<string> IPv4_lst;
string segment;
while (getline(ss, segment, '#')) {
IPv4_lst.push_back(segment);
}
bool isError = false;
if (IPv4_lst.size() != 4) {
isError = true;
} else if (!areAllDigits(IPv4_lst)) {
isError = true;
} else if (stol(IPv4_lst[0]) > 128 || stol(IPv4_lst[0]) == 0) {
isError = true;
} else if (!areAllInRange(IPv4_lst, 1, 3)) {
isError = true;
} else {
vector<string> IPv4_lst_16base;
for (const string& num : IPv4_lst) {
stringstream hexStream;
hexStream << hex << stol(num);
string hexNum = hexStream.str();
if (hexNum.length() < 2) {
hexNum = "0" + hexNum;
}
IPv4_lst_16base.push_back(hexNum);
}
string IPv4_str_16base = "";
for (const string& num : IPv4_lst_16base) {
IPv4_str_16base += num;
}
long ans = stol(IPv4_str_16base, nullptr, 16);
cout << ans << endl;
}
if (isError) {
cout << "invalid IP" << endl;
}
return 0;
}
时间复杂度:O(1)
。常数级别的操作。
空间复杂度:O(1)
。常数级别的内存。
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务300+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多