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

2024-01-20 14:36

本文主要是介绍根据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加群”

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

这篇关于根据IP查找城市 - 华为OD统一考试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626327

相关文章

C#实现查找并删除PDF中的空白页面

《C#实现查找并删除PDF中的空白页面》PDF文件中的空白页并不少见,因为它们有可能是作者有意留下的,也有可能是在处理文档时不小心添加的,下面我们来看看如何使用Spire.PDFfor.NET通过C#... 目录安装 Spire.PDF for .NETC# 查找并删除 PDF 文档中的空白页C# 添加与删

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

售价599元起! 华为路由器X1/Pro发布 配置与区别一览

《售价599元起!华为路由器X1/Pro发布配置与区别一览》华为路由器X1/Pro发布,有朋友留言问华为路由X1和X1Pro怎么选择,关于这个问题,本期图文将对这二款路由器做了期参数对比,大家看... 华为路由 X1 系列已经正式发布并开启预售,将在 4 月 25 日 10:08 正式开售,两款产品分别为华

Python中使用正则表达式精准匹配IP地址的案例

《Python中使用正则表达式精准匹配IP地址的案例》Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋... 目录为什么需要IP正则表达式?IP地址的基本结构基础正则表达式写法精确匹配0-255的数字验证IP地

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Linux配置IP地址的三种实现方式

《Linux配置IP地址的三种实现方式》:本文主要介绍Linux配置IP地址的三种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录环境RedHat9第一种安装 直接配置网卡文件第二种方式 nmcli(Networkmanager command-line

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想