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:

    1. ip will be a valid IPv4 address.
    2. Every implied address ip + x (for x < n) will be a valid IPv4 address.
    3. n will 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));
}
};

类似题目:

Validate IP Address

Restore IP Addresses

参考资料:

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无类别域间路由的更多相关文章

  1. CIDR 无类别域间路由

    参考百度百科 1.全称 CIDR的全称是Classless Inter-Domain Routing 2.作用 CIDR将路由集中起来,使一个IP地址代表主要骨干提供商服务的几千个IP地址,从而减轻I ...

  2. Ip地址和子网掩码和CIDR无间别域间路由

    开始,网络的制定者将网络划分为A,B,C三种网络,想这个样子: A类网:  xxx.0.0.0         子网掩码:255.0.0.0 xxx.0.0.0/8 //后面的数字代表网络地址的字段 ...

  3. CIDR(无类域间路由)(转载)

    来源:百度百科 CIDR(无类型域间选路,Classless Inter-Domain Routing)是一个在Internet上创建附加地址的方法,这些地址提供给服务提供商(ISP),再由ISP分配 ...

  4. 互联网自治域间IP源地址验证技术综述

    一.文章信息 作者:贾溢豪,任罡,刘莹 单位:清华大学 来源:软件学报 时间:2017年 二.基于加密.签名及标记信息 2.1 技术原理 采用端到端验证的设计结构,其中以密钥协商最为常见.通信双方在事 ...

  5. 如何计算IP地址及CIDR(收藏)

    如何计算IP地址及CIDR 一. IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主 机ID用来标 ...

  6. 如何计算IP地址及CIDR,子网掩码计算

    如何计算IP地址及CIDR 一. IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机.网络ID用来标识计算机所处的网段:主 机ID用来标 ...

  7. IP地址和CIDR

    IP地址(IPV4) IPV4的地址是一个32位的二进制数,由网络ID和主机ID两部分组成,用来在网络中唯一的标识一台计算机.IP地址通常用四组3位的十进制数表示,中间用.分割,例如:192.168. ...

  8. CIDR的IP地址的表示与划分方法

    早期的ip地址划分: 最初设计互联网络时,为了便于寻址以及层次化构造网络,每个IP地址包括两个标识码(ID),即网络ID和主机ID.同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包 ...

  9. [转帖]IP地址和CIDR

    IP地址和CIDR https://www.cnblogs.com/cocowool/p/8303795.html 感谢原作者 自己竟然忘记了 classless inter-domain route ...

随机推荐

  1. shiro权限框架(五)

    五.与Spring集成 5.1 环境准备 <dependency> <groupId>org.apache.shiro</groupId> <artifact ...

  2. java中equals相同,hashcode一定相同ma

    一.jdk中equals和hashcode的定义和源码进行分析 1.java.lang.Object中对equals()方法的定义 java.lang.Object中对hashCode()方法的定义 ...

  3. Ubuntu16.0.4的磁盘管理

    ubuntu下硬盘无损分区移动修改工具 原创 2014年04月13日 :: ubuntu上面其实有很好的分区调整工具,gparted,非常好使用 安装非常简单 sudo apt-get install ...

  4. 一个基于H5audio标签的vue音乐播放器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Struts2学习笔记五 拦截器

    拦截器,在AOP中用于在某个方法或字段被访问之前,进行拦截,然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. Struts2中,拦截器是动态拦截Action调用的对象.它提供了一种机制可以使 ...

  6. 四则运算程序(java基于控制台)

    四则运算题目生成程序(基于控制台) 一.题目描述: 1. 使用 -n 参数控制生成题目的个数,例如 Myapp.exe -n 10 -o Exercise.txt 将生成10个题目. 2. 使用 -r ...

  7. 105&250-高级软件工程2017第3次作业

    小组成员 2017282110250 王婷婷 2017202110105 张芷祎 github地址 https://github.com/setezzy/Calculator_GUI PSP PSP2 ...

  8. 百词斩APP分析

    一.调研 1.第一次上手   第一次使用,可以使用微信和qq登录感觉挺不错的不然又要注册有点麻烦,在功能上,用户可以针对自身选择不同水平的英语背单词,然后有多钟方式对自己的听力和单词翻译进行提升.在u ...

  9. Python实现栈

    栈的操作 Stack() 创建一个新的空栈 push(item) 添加一个新的元素item到栈顶 pop() 弹出栈顶元素 peek() 返回栈顶元素 is_empty() 判断栈是否为空 size( ...

  10. iOS开发-添加圆角效果高效实现

    圆角(RounderCorner)是一种很常见的视图效果,相比于直角,它更加柔和优美,易于接受.但很多人并不清楚如何设置圆角的正确方式和原理.设置圆角会带来一定的性能损耗,如何提高性能是另一个需要重点 ...