根据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,一经查实,立即删除!

相关文章

非线性最小二乘问题的数值方法 —— 狗腿法 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…

基于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.创建…

设计模式篇章(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><…

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 复…

扎克伯格宣布将购买35万个GPU

Meta公司马克.扎克伯格1月18日在Instagram上发表文章称&#xff0c;该公司正在加强人工智能研究团队的力量&#xff0c;并在充实AI基础设施“弹药库“&#xff0c;计划在今年年底前向芯片设计商英伟达购买35万个H100 GPU芯片&#xff0c;从而使该公司的GPU总量达到约60万个&…

利用预训练模型SKEP进行情感分析

项目地址&#xff1a;文本情感分析 - 飞桨AI Studio星河社区 (baidu.com) baidu/Senta: Baidus open-source Sentiment Analysis System. (github.com) 本项目将详细全面介绍情感分析任务的两种子任务&#xff0c;句子级情感分析和目标级情感分析。 同时演示如何使用情感分析…

线性规划案例分享

今天想写一个最优传输的简单实现&#xff0c;结果学歪了&#xff0c;学到线性规划去了&#xff0c;这里我发现了一个宝藏网站 虽然是讲计量经济的&#xff0c;但是里面提供的公式和代码我很喜欢&#xff0c;有时间可以好好读一下 https://python.quantecon.org/lp_intro.html …

如何一键部署本地Java项目到服务器上

一、背景 我开发了一个Java代码&#xff0c;现在想部署到服务器上&#xff0c;当然可以使用Jenkins部署&#xff0c;但是Jenkins配置和维护成本比较高&#xff0c;所以我今天分享的是轻量级的一键部署脚本 演示&#xff1a;本地Window的Java代码 -> Vmware虚拟机Centos7上…

面试题:RabbitMQ 有哪几种消息模式?

文章目录 前言核心组成Rabbitmq 消息模式3.1 Simple 模式ProductorCustomer 3.2 Fanout 模式ProductorCustomer 3.3 Direct 模式Productor 3.4 Topic 模式Productor 3.5 Work 模式3.5.1 轮询分发ProductorWorker1 3.5.2 公平分发Worker1 防止消息丢失机制4.1 消息确认4.2 持久化…

在WIN从零开始在QMUE上添加一块自己的开发板(一)

文章目录 一、前言二、源码编译&#xff08;一&#xff09;安装Msys2&#xff08;二&#xff09;配置GCC工具链&#xff08;三&#xff09;安装QEMU构建依赖&#xff08;四&#xff09;下载编译QEMU源码 二、QUME编程基础&#xff08;一&#xff09;QOM机制&#xff08;二&…

LabVIEW振动筛螺栓松动故障诊断

LabVIEW振动筛螺栓松动故障诊断 概述&#xff1a;利用LabVIEW解决振动筛螺栓松动的故障诊断问题。通过集成的方法&#xff0c;不仅提高了故障检测的准确性&#xff0c;还优化了维护流程&#xff0c;为类似的机械设备故障提供了可靠的解决方案。 由于工作条件复杂&#xff0c;…