[LeetCode] IP to CIDR 将IP地址转为CIDR无类别域间路由
Given a start IP address ip and a number of ips we need to cover n, return a representation of the range as a list (of smallest possible length) of CIDR blocks.
A CIDR block is a string consisting of an IP, followed by a slash, and then the prefix length. For example: "123.45.67.89/20". That prefix length "20" represents the number of common prefix bits in the specified range.
Example 1:
Input: ip = "255.0.0.7", n = 10
Output: ["255.0.0.7/32","255.0.0.8/29","255.0.0.16/32"]
Explanation:
The initial ip address, when converted to binary, looks like this (spaces added for clarity):
255.0.0.7 -> 11111111 00000000 00000000 00000111
The address "255.0.0.7/32" specifies all addresses with a common prefix of 32 bits to the given address,
ie. just this one address. The address "255.0.0.8/29" specifies all addresses with a common prefix of 29 bits to the given address:
255.0.0.8 -> 11111111 00000000 00000000 00001000
Addresses with common prefix of 29 bits are:
11111111 00000000 00000000 00001000
11111111 00000000 00000000 00001001
11111111 00000000 00000000 00001010
11111111 00000000 00000000 00001011
11111111 00000000 00000000 00001100
11111111 00000000 00000000 00001101
11111111 00000000 00000000 00001110
11111111 00000000 00000000 00001111 The address "255.0.0.16/32" specifies all addresses with a common prefix of 32 bits to the given address,
ie. just 11111111 00000000 00000000 00010000. In total, the answer specifies the range of 10 ips starting with the address 255.0.0.7 . There were other representations, such as:
["255.0.0.7/32","255.0.0.8/30", "255.0.0.12/30", "255.0.0.16/32"],
but our answer was the shortest possible. Also note that a representation beginning with say, "255.0.0.7/30" would be incorrect,
because it includes addresses like 255.0.0.4 = 11111111 00000000 00000000 00000100
that are outside the specified range.
Note:
ipwill be a valid IPv4 address.- Every implied address
ip + x(forx < n) will be a valid IPv4 address. nwill be an integer in the range[1, 1000].
这道题博主刚开始做的时候,看了半天,读不懂题目的意思,结果一看是一道Easy的题,直接???尼克杨问号脸???后来通过研究论坛上大家的解法,才总算明白了这道题让我们做什么。此题给了我们一个用字符串表示的ip地址,还有一个整数n,让我们以给定的ip地址为起点,需要覆盖n个ip地址。而这n个ip地址的写法使用无类别域间路由CIDR块来写,所谓的CIDR块,是由一个正常的ip地址,加上斜杠数字,斜杠后面的数字表示这些ip地址具有相同的前缀的个数,比如"255.0.0.7/32",如果有32个相同的前缀,说明只有唯一的一个ip地址,因为IPv4总共就只有32位。再比如"255.0.0.8/29",表示有29个相同的前缀,那么最后3位可以自由发挥,2的3次方为8,所以就共有8个ip地址。同理,"255.0.0.16/32"只表示一个地址,那么这三个CIDR块总共覆盖了10个地址,就是我们要求的结果。
由于题目中要求尽可能少的使用CIDR块,那么在n确定的情况下,CIDR块能覆盖的越多越好。根据我们前面的分析,当CIDR块斜杠后面的数字越小,该块覆盖的ip地址越多。那么就是说相同前缀的个数越少越好,但是我们的ip地址又不能小于给定的ip地址,所以我们只能将0变为1,而不能将1变为0。所以我们的选择就是有将最低位1后面的0进行变换,比如"255.0.0.8"末尾有3个0,可以变换出8个不同的地址。那么我们只要找出末尾1的位置,就知道能覆盖多少个地址了。找末尾1有个trick,就是利用 x & -x 来快速找到,这个trick在之前做的题中也有应用。知道了最多能覆盖地址的数量,还要考虑到n的大小,不能超过n,因为题目只要求覆盖n个。确定了覆盖的个数,我们就可以进行生成CIDR块的操作了,之前我们为了求 x & -x,将ip地址转为了一个十进制的数,现在我们要把每一块拆分出来,直接按对应位数量进行右移并与上255即可,斜杠后的数字计算通过覆盖的个数进行log2运算,再被32减去即可,参见代码如下:
class Solution {
public:
vector<string> ipToCIDR(string ip, int n) {
vector<string> res;
long x = ;
istringstream is(ip);
string t;
while (getline(is, t, '.')) {
x = x * + stoi(t);
}
while (n > ) {
long step = x & -x;
while (step > n) step /= ;
res.push_back(convert(x, step));
x += step;
n -= step;
}
return res;
}
string convert(long x, int step) {
return to_string((x >> ) & ) + "." + to_string((x >> ) & ) + "." + to_string((x >> ) & ) + "." + to_string(x & ) + "/" + to_string( - (int)log2(step));
}
};
类似题目:
参考资料:
https://discuss.leetcode.com/topic/115127/10-lines-java-solution
https://discuss.leetcode.com/topic/114848/very-simple-java-solution-beat-100
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] IP to CIDR 将IP地址转为CIDR无类别域间路由的更多相关文章
- CIDR 无类别域间路由
参考百度百科 1.全称 CIDR的全称是Classless Inter-Domain Routing 2.作用 CIDR将路由集中起来,使一个IP地址代表主要骨干提供商服务的几千个IP地址,从而减轻I ...
- Ip地址和子网掩码和CIDR无间别域间路由
开始,网络的制定者将网络划分为A,B,C三种网络,想这个样子: A类网: xxx.0.0.0 子网掩码:255.0.0.0 xxx.0.0.0/8 //后面的数字代表网络地址的字段 ...
- CIDR(无类域间路由)(转载)
来源:百度百科 CIDR(无类型域间选路,Classless Inter-Domain Routing)是一个在Internet上创建附加地址的方法,这些地址提供给服务提供商(ISP),再由ISP分配 ...
- 互联网自治域间IP源地址验证技术综述
一.文章信息 作者:贾溢豪,任罡,刘莹 单位:清华大学 来源:软件学报 时间:2017年 二.基于加密.签名及标记信息 2.1 技术原理 采用端到端验证的设计结构,其中以密钥协商最为常见.通信双方在事 ...
- 如何计算IP地址及CIDR(收藏)
如何计算IP地址及CIDR 一. IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主 机ID用来标 ...
- 如何计算IP地址及CIDR,子网掩码计算
如何计算IP地址及CIDR 一. IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主 机ID用来标 ...
- IP地址和CIDR
IP地址(IPV4) IPV4的地址是一个32位的二进制数,由网络ID和主机ID两部分组成,用来在网络中唯一的标识一台计算机.IP地址通常用四组3位的十进制数表示,中间用.分割,例如:192.168. ...
- CIDR的IP地址的表示与划分方法
早期的ip地址划分: 最初设计互联网络时,为了便于寻址以及层次化构造网络,每个IP地址包括两个标识码(ID),即网络ID和主机ID.同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包 ...
- [转帖]IP地址和CIDR
IP地址和CIDR https://www.cnblogs.com/cocowool/p/8303795.html 感谢原作者 自己竟然忘记了 classless inter-domain route ...
随机推荐
- Flash Builder4.7安装破解
引用自CSDN博客,日后我会上传FlashBuilder到百度网盘谢谢 http://bbs.csdn.net/topics/391036327
- Welcome to Django!
Welcome to Django! 实验简介 Django是一个可以使Web开发工作更加高效愉快的Web开发框架.Django可以让你用最小的代价构建和维护更高质量的Web应用程序. 从好的方面来看 ...
- Django 个性化管理员站点
from django.contrib import admin # Register your models here. from .models import Moment class Momen ...
- MobileNet_v2
研究动机: 神经网络彻底改变了机器智能的许多领域,实现了超人的准确性.然而,提高准确性的驱动力往往需要付出代价:现代先进网络需要高度计算资源,超出许多移动和嵌入式应用的能力. 主要贡献: 发明了一个新 ...
- Python爬虫基本原理
爬虫基本原理 1. 什么是爬虫 请求网站并提取数据的自动化程序. 2. 爬虫基本流程 发起请求 通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待 ...
- python全栈开发-logging模块(日记专用)
一.概述 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,l ...
- Linq GroupBy
//Linq //var result = from p in personList // group p by p.Id // into grouped // select new { Id = g ...
- Python-进程与线程理论基础-Day10
进程与线程理论基础 1.背景知识 理论基础: 一 操作系统的作用: 1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口 2:管理.调度进程,并且将多个进程对硬件的竞争变得有序 二 多道技术: 1.产生背景 ...
- restful架构风格设计准则(二)以资源为中心,一个url
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 1.REST是一种架构风格,其核心是面向资源,简化设计,降低开发的复杂性 ...
- [SQL case when的两种用法]
当我们需要从数据源上 直接判断数据显示代表的含义的时候 ,就可以在SQL语句中使用 Case When这个函数了. Case具有两种格式.简单Case函数和Case搜索函数. 第一种 格式 : 简单C ...