| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 程序员的算法趣题Q40: 优雅的IP地址 -> 正文阅读 |
|
[C++知识库]程序员的算法趣题Q40: 优雅的IP地址 |
作者:https://blog.csdn.net/chenxy_bwave/article/details/119849548 |
目录 1. 问题描述????????IPv4 中的 IP 地址是二进制的 32 位数值。不过,这样的数值对我们人类而言可读性比较差,所以我们通常会以 8 位为 1 组分割,用类似 192.168.1.2 这种十进制数来表示它(图 1)。 ? 图 1 IP 地址(IPv4) ????????这里,我们思考一下十进制数 0~9 这 10 个数字各出现 1 次的 IP 地址(像正常情况一样,省略每组数字首位的 0。也就是说,不能像 192.168.001.002 这样表示,而要像 192.168.1.2 这样来表示)。 ????????问题:求用二进制数表示上述形式的 IP 地址时,能使二进制数左右对称的 IP 地址的个数(用二进制数表示时不省略 0,用完整的 32 位数表示)。 ? 2. 解题分析2.1 笨办法????????10个数共有10!种排列。IPv4的第一个字段允许为0吗?如果不允许的话,则应该是9*9!。注意,题中的要求是省略每组数字首位的 0,但是单独的0至少对于后面几个字段是允许的。这里先假定第一个字段也允许为0,反正只是定性的分析,差异不大。 ????????将每种排列分割成4段,相当于在9个位置种插入3个分割点。如果第一个数是0,则0后面必须放一个分割点,则总共有C(8,2)种分割点放置方式;如果第一个数不是0,则分割必须不出现在0的前面,因此总共有C(8,3)种分割点放置方式。综合考虑有C(8,2)+9*C(8,3)种分割点放置方式。 ????????然后再进一步去判断这每一种分割方式所生成的IP是否符合题设的要求(每个字段必须在[0,255]之间,且转换成32比特二进制表示后左右对称)。 ????????因此总共需要检查(10!)*( C(8,2)+9*C(8,3))= 1930521600种可能的IP。这是一个巨大的数字,有没有办法削减搜索范围? 2.2 逆向思考????????IPv4的每个字段为8比特,十进制表示范围是从0~255。以A、B、C、D分别表示第1、2、3、4个字段的十进制表示的话,如果使得整体用32比特表示的二进制为对称的话,则必然A和D、B和C作为8比特的二进制表示分别构成对称对(顺便说一下,原书的提示不知道是不是翻译的问题,说的非常含糊容易引起误导)。因此,事实上只要对两个8比特数的组合进行扫描,对每一种组合在进一步判断十进制表示是不是刚好包含0~9各1个的10个数字。共有256*256=65536种可能的组合,这个组合数远远地小于上一节的方案。 ????????以下代码按照这种思路来实现。其中有一些小巧的细节,说明如下: ? ? ? ?(1) 十进制数转换成二进制数用bin(),但是bin()的输出前面包含’0b’前缀。所以后跟[2:]去除这个前缀。如下所示:
? ? ? ? (2) 求对称的二进制序列。由于bin()的输出可能不满8比特长。但是在判断二进制序列是否相互对称时是考虑双方都是8比特(不足8比特的先头补0),因此在求与A互补的D的二进制表示时首先用Abin[::-1]取Abin的reverse,然后再在尾部根据需要补0(因为A是头部补0)。如下所示:
? ? ? ? (3) 将二进制转换成十进制,int()函数有参数只是原字符串的进制数,二进制的话则设为2.如下所示:
? ? ? ? (4) 判断是否是刚好0~9各包含一个的10个数。将A、B、C、D变成字符串然后串联起来,然后再传换成set(因为set的元素是unique的,自动剔除重复的元素),因此最后只要判断该set的长度是不是10即可。如下所示:
3. 代码及测试
运行结果: ????????nums=8, tCost = ?0.152(sec) ? ? ? ? 上一篇:Q31: 计算最短路径 ? ? ? ? 下一篇:Q42: 将牌洗为逆序 ????????本系列总目录参见:程序员的算法趣题:详细分析和Python全解 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 20:38:18- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |