根据IP查找城市 - 华为OD统一考试

OD统一考试

题解: Java / Python / C++

alt

题目描述

某业务需要根据终端的IP地址获取该终端归属的城市,可以根据公开的IP地址池信息查询归属城市。

地址池格式如下:

城市名=起始IP,结束IP

起始和结束地址按照英文逗号分隔,多个地址段采用英文分号分隔。

比如:
City1=1.1.1.1,1.1.1.2;City1=1.1.1.11,1.1.1.16;City2=3.3.3.3,4.4.4.4;City3=2.2.2.2,6.6.6.6。

一个城市可以有多个IP段,比如City1有2个IP段。

城市间也可能存在包含关系,比如City3的IP段范围包括City2的IP段范围。

现在要根据输入的IP列表,返回最佳匹配的城市列表。

注:最佳匹配即可包含待查询IP且长度最小的IP段,比如例子中的
3.4.4.4的最佳匹配是City2=3.3.3.3,4.4.4.4;
5.5.5.5的最佳匹配是City3=2.2.2.2,6.6.6.6。

输入描述

输入共2行。

第一行为城市的IP段列表,多个IP段采用英文分号’;'分隔,IP段列表最大不超过500000。

城市名称只包含英文字母、数字和下划线,最多不超过100000个。

IP段包含关系可能有多层,但不超过100层。

第二行为查询的IP列表,多个IP采用英文逗号’,'分隔,最多不超过10000条。

输出描述

最佳匹配的城市名列表,采用英文逗号,分隔,城市列表长度应该跟查询的IP列表长度一致。

示例1

输入:
City1=1.1.1.1,1.1.1.2;City1=1.1.1.11,1.1.1.16;City2=3.3.3.3,4.4.4.4;City3=2.2.2.2,6.6.6.6
1.1.1.15,3.3.3.5,2.2.2.3输出:
City1,City2,City3

题解

这道题目涉及到对IP地址范围的处理和匹配,可以通过以下步骤解决:

  1. 将输入的IP范围按照起始IP排序,以便后续的查找操作。
  2. 对于每个待查询的IP,从排序后的IP范围列表中找到满足条件的最佳匹配,即包含待查询IP且长度最小的IP段。
  3. 输出最佳匹配的城市列表。

在此题目中为了方便的对 ip 进行处理,代码中将字符串的ip转成了等价的正整数。

具体实现中,可以使用类来表示IP范围,然后对IP范围列表进行排序。

在查询时,遍历排序后的IP范围列表,找到最佳匹配的城市。

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;class IpRange {public String city;public long startIp;public long endIp;public IpRange(String city, long startIp, long endIp) {this.city = city;this.startIp = startIp;this.endIp = endIp;}
}/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);List<IpRange> ipRanges = new ArrayList<>();// 读取 IP 范围并进行排序String[] rangeInputs = scanner.nextLine().split(";");for (String rangeInput : rangeInputs) {String[] parts = rangeInput.split("=");String city = parts[0];String[] ipRange = parts[1].split(",");long startIp = ipToLong(ipRange[0]), endIp = ipToLong(ipRange[1]);ipRanges.add(new IpRange(city, startIp, endIp));}ipRanges.sort((x, y) -> (int) (x.startIp - y.startIp));// 查询并输出结果String[] ipInputs = scanner.nextLine().split(",");List<String> results = new ArrayList<>();for (String ipInput : ipInputs) {results.add(findCity(ipRanges, ipToLong(ipInput)));}System.out.println(String.join(",", results));}/*** IP 字符串转成10进制的整数** @param ip* @return*/private static long ipToLong(String ip) {String[] ipParts = ip.split("\\.");return (0L | Integer.parseInt(ipParts[0]) << 24) |(Integer.parseInt(ipParts[1]) << 16) |(Integer.parseInt(ipParts[2]) << 8) |Integer.parseInt(ipParts[3]);}/*** 根据IP 查询归属城市, 返回最佳匹配城市名称(既满足条件且长度最小的IP段)** @param ipRanges* @param ip* @return*/private static String findCity(List<IpRange> ipRanges, long ip) {String city = "unknown";long cityLength = Long.MAX_VALUE;for (IpRange ipRange : ipRanges) {if (ipRange.startIp > ip) break;long length = ipRange.endIp - ipRange.startIp + 1;if (ipRange.startIp <= ip && ip <= ipRange.endIp && length < cityLength) {cityLength = length;city = ipRange.city;}}return city;}
}

Python


from math import inf
import stringdef ip_to_int(ip: string):""" IP 字符串转成10进制的整数 """ip_nums = list(map(int, ip.split('.')))return ip_nums[0] << 24 | ip_nums[1] << 16 | ip_nums[2] << 8 | ip_nums[3]class IpRange:""" IP范围 """def __init__(self, city, start_ip, end_ip):self.start_ip = ip_to_int(start_ip)self.end_ip = ip_to_int(end_ip)self.city = cityip_ranges = []
for sip in input().split(";"):city, iprange = sip.split("=")start_ip, end_ip = iprange.split(",")ip_ranges.append(IpRange(city, start_ip, end_ip))# 根据 x.start_ip 升序 进行排序
ip_ranges.sort(key=lambda x: x.start_ip)def find_city(ip):""" 根据IP 查询归属城市 """global ip_ranges# 返回最佳匹配城市名称(既满足条件且长度最小的IP段)city, city_length = "unknown", inffor it in ip_ranges:if it.start_ip > ip:breaklenght = it.end_ip - it.start_ip + 1if it.start_ip <= ip <= it.end_ip and lenght < city_length:city_length = lenghtcity = it.cityreturn cityrs = []
for sip in input().split(","):rs.append(find_city(ip_to_int(sip)))
print(",".join(rs))

C++

#include <bits/stdc++.h>using namespace std;class IpRange {
public:string city;long startIp;long endIp;IpRange(string city, long startIp, long endIp): city(move(city)), startIp(startIp), endIp(endIp) {}
};// IP 字符串转成10进制的整数
long ipToLong(const string& ip) {istringstream iss(ip);string token;long result = 0;while (getline(iss, token, '.')) {result = (result << 8) | stoi(token);}return result;
}// 根据IP 查询归属城市, 返回最佳匹配城市名称(既满足条件且长度最小的IP段)
string findCity(const vector<IpRange>& ipRanges, long ip) {string city = "unknown";long cityLength = LONG_MAX;for (const auto& ipRange : ipRanges) {if (ipRange.startIp > ip) break;long length = ipRange.endIp - ipRange.startIp + 1;if (ipRange.startIp <= ip && ip <= ipRange.endIp && length < cityLength) {cityLength = length;city = ipRange.city;}}return city;
}vector<string> split(const string &str, const char &delim) {vector<string> res;stringstream ss(str);string tmp;while (getline(ss, tmp, delim)) {if (!tmp.empty()) res.push_back(std::move(tmp));}return res;
}int main() {vector<IpRange> ipRanges;// 读取 IP 范围并进行排序string inputLine;getline(cin, inputLine);vector<string> parts = split(inputLine, ';');for(string& part : parts) {vector<string> arr = split(part, '=');string city = arr[0];vector<string> ips = split(arr[1], ',');ipRanges.emplace_back(city, ipToLong(ips[0]), ipToLong(ips[1]));}sort(ipRanges.begin(), ipRanges.end(), [](const auto& x, const auto& y) {return x.startIp < y.startIp;});// 查询并输出结果getline(cin, inputLine);vector<string> results;for(auto& ip : split(inputLine,',')) {results.push_back(findCity(ipRanges, ipToLong(ip)));}for(int i=0; i<results.size(); i++) {if(i + 1 == results.size()) {cout << results[i] << endl;} else {cout << results[i] << ",";}}return 0;
}

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/635630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python字母异位词分组

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate", "nat", &…

非线性最小二乘问题的数值方法 —— 狗腿法 Powell‘s Dog Leg Method (I - 原理与算法)

Title: 非线性最小二乘问题的数值方法 —— 狗腿法 Powell’s Dog Leg Method (I - 原理与算法) 文章目录 I. 前言II. 线搜索类型和信赖域类型1. 线搜索类型 —— 最速下降法2. 信赖域类型3. 柯西点 III. 狗腿法的原理1. 狗腿法的构建2. 狗腿法的优化说明3. 狗腿法的插值权重 I…

Java 全栈知识点问题汇总(上)

Java 全栈知识点问题汇总&#xff08;上&#xff09; 1 Java 基础 1.1 语法基础 面向对象特性&#xff1f;a a b 与 a b 的区别3*0.1 0.3 将会返回什么? true 还是 false?能在 Switch 中使用 String 吗?对equals()和hashCode()的理解?final、finalize 和 finally 的不同…

Git 配置与理解

简述 Git 在 Windows 和 Ubuntu 中的配置&#xff0c;以及对 Git 工作区域划分和 Git 中对于文件状态划分的理解。 git 基础安装与配置 基于 WSL 的 Ubuntu 下的 git 打开或关闭Windows功能 -> Hyper-V、Virtual Machine Platform、Windows Subsystem for Linux # 1.必须…

STM32407用汇顶的GT911触摸芯片调试实盘

这个配置很关键 代码 #include "stm32f4xx.h" #include "GT9147.h" #include "Touch.h" #include "C_Touch_I2C.h" #include "usart.h" #include "delay.h" #include "LCD.h" #incl…

x86 和 x64 arm的区别

x86和x64是基于英特尔x86架构的复杂指令集架构&#xff08;ISA&#xff09;&#xff0c;而ARM是一种精简指令集架构。 什么是指令集架构 假设我们现在要开发一个cpu&#xff0c;就好比说我们去修建一栋楼&#xff0c;开发商会先将图纸设计好。设计好之后由施工单位按照设计图…

openssl3.2 - 官方demo学习 - signature - EVP_DSA_Signature_demo.c

文章目录 openssl3.2 - 官方demo学习 - signature - EVP_DSA_Signature_demo.c概述笔记END openssl3.2 - 官方demo学习 - signature - EVP_DSA_Signature_demo.c 概述 DSA签名(摘要算法SHA256), DSA验签(摘要算法SHA256) 签名 : 用发送者的私钥进行签名. 验签 : 用发送者的公…

基于SSM的图书馆管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的图书馆管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Sp…

win系统环境搭建(十四)——Windows系统下使用docker安装mysql8和mysql5.7

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7 文章目录 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7MySQL81.新建文件夹2.创建…

windows开机默认启动某个程序

在Windows操作系统中&#xff0c;你可以通过将程序添加到“启动”文件夹或使用任务计划程序来实现开机自动启动某个程序。以下是两种常见的方法&#xff1a; 方法 1&#xff1a;使用“启动”文件夹 找到启动文件夹 按 Win R 打开运行对话框。输入 shell:startup&#xff0c;然…

Webpack5入门到原理1:前言

为什么需要打包工具&#xff1f; 开发时&#xff0c;我们会使用框架&#xff08;React、Vue&#xff09;&#xff0c;ES6 模块化语法&#xff0c;Less/Sass 等 css 预处理器等语法进行开发。 这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、Css 等语法&#xf…

Golang 中的反射,并用来获取数据类型

Go语言提供了一种机制在运行中获取某个变量的类型&#xff0c;获取或修改变量的值&#xff0c;调用变量的方法。 示例代码如下 1. 使用 x.(type)获取变量类型 package mainimport "strconv" //StrPrint 将几种已知数据类型转化为 string func StrPrint(x interfac…

设计模式篇章(4)——十一种行为型模式

这个设计模式主要思考的是如何分配对象的职责和将对象之间相互协作完成单个对象无法完成的任务&#xff0c;这个与结构型模式有点像&#xff0c;结构型可以理解为静态的组合&#xff0c;例如将不同的组件拼起来成为一个更大的组件&#xff1b;而行为型更是一种动态或者具有某个…

three.js从入门到精通系列教程016 - three.js通过OrbitControls对立方体实现旋转和缩放

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>three.js从入门到精通系列教程016 - three.js通过OrbitControls对立方体实现旋转和缩放</title><script src"ThreeJS/three.js"></script><…

CentOS 7 安装Jdk 配置环境变量

在CentOS 7操作系统中&#xff0c;安装JDK并配置环境变量的具体步骤如下&#xff1a; 第一步、需要检查系统是否自带JDK&#xff0c;并删除已有的JDK。 第二步、下载JDK8或其它版本的安装包&#xff0c;并解压到一个新建的Java目录中。 第三步、配置环境变量。将JAVA_HOME变量设…

EasyRecovery2024免费电脑数据恢复软件下载

easyrecovery是一款功能强大、易于使用的硬盘数据恢复软件。这款软件可以帮助用户非常方便地恢复丢失的数据。软件非常容易使用和高效的数据恢复。感兴趣的朋友们赶快来下载吧。 无论是因为意外删除、格式化、病毒感染、系统崩溃还是其他原因&#xff0c;该软件可以帮助您恢复…

你还在找PDF转Word的工具?一个好软件推荐,赶紧查收!

前言 前段时间朋友跟小白吐槽&#xff1a;为啥PDF文件转Word文档的工具都要收费&#xff1f; 因为他们都收费啊。 小白之前找了很多类似有这种功能的工具&#xff0c;都发现&#xff1a;不但收费&#xff0c;可能还附带全家桶&#xff0c;而且还有……广告&#xff01; 在一次…

Pytest插件“pytest-selenium” - 让自动化测试更简洁

在现代Web应用的开发中,自动化测试成为确保网站质量的重要手段之一。而Pytest插件 pytest-selenium 则为开发者提供了简单而强大的工具,以便于使用Python进行Web应用的自动化测试。本文将深入介绍 pytest-selenium 插件的基本用法和实际案例,助你轻松进入无忧的Web应用测试之…

中文词向量训练-案例分析

1 数据预处理&#xff0c;解析XML文件并分词 #!/usr/bin/env python # -*- coding: utf-8 -*- # process_wiki_data.py 用于解析XML&#xff0c;将XML的wiki数据转换为text格式 import logging import os.path import sys from gensim.corpora import WikiCorpus import jieba…

phpStorm 设置终端为git bash

环境&#xff1a; windows , PhpStorm 2022 为自己的终端配置git样式的使用&#xff0c; 默认终端样式 一、打开设置&#xff0c;选择git bin 二、重新打开终端 不加--login -i 的终端 加了--login -i 的终端 最重要的一点是什么&#xff0c;他可以像mac一样支持 ctrlv 复…