看到的文章链接如下https://mp.weixin.qq.com/s/8G...
题目如下
/** 2. 寻找特定 IP
IPV4 的 IP 地址是32位的二进制数,为增强可读性,通常我们以8位为1组进行分割,
用十进制来表示每一部分,并用点号连接,譬如 192.168.1.1。显然,存在这样的 IP 地址,
0到9十个数字各出现一次。具备这样特征的 IP 地址里,表示成二进制数时,二进制数左右对称
(也就是“回文”,表示成32位二进制不省略0)的情况有几种,分别是哪些?要求性能尽可能高
*/
记录下 最后结果是4种 有点类似算法题两数之和 可能还有更好的解法 暂时还没想到
题意就是找个ipv4地址 0-9十个数字各出现一次比如189.267.45.30 并且每个以.分割后的数字之后全转化为9位的二进制补0 最后合并成的字符为回文
转ip为二进制流程
const transIPTobinary = (IP) => {
let arr = IP.split(".")
let res = ''
arr.map(num => {
res += (num).toString(2).padStart(8, 0) // 转为2进制后一共需要8位并补0
})
return res
}
ipv4由4个数字组成以点分割,每位0-255. 比如说189.267.45.30
假定189.267.45.30是我们寻找的特定IP。那么189转为2进制 跟30转为2进制两者相加一定是回文,两者一定是相对中心对称的,267跟45也是如此 两者相加也是回文。考虑每个数字出现一次,如果自身转化为2进制就已经是回文的不做考虑 比如0跟255的情况 00000000 11111111
所以想清楚后接下来的事就比较简单
关键在于寻找自身和自身翻转后对应的那一组数字
var findSpecialIP = function() {
let res = []
let m = new Map()
let group = []
var isPalindrome = function(x) { // 检查回文
return x.toString() == x.toString().split("").reverse().join("");
};
let hasRepeatNum = function(...args) {
let a = args.toString()
let b = [...new Set(a.split(""))]
return a.length !== b.length
}
let lenIs10 = function(...args) {
return args[0].join("").length === 10
}
let getIp = function([a,b], [c,d]) { //[16,8] [32,4]
return [
`${a}.${c}.${d}.${b}`,
`${b}.${c}.${d}.${a}`,
`${a}.${d}.${c}.${b}`,
`${b}.${d}.${c}.${a}`
]
}
for(let i = 0; i< 256; i++ ) {
if(!hasRepeatNum(i) || i < 11) {
let self = (i).toString(2).padStart(8, 0) // 转为2进制后一共需要8位并补0
let re = self.split("").reverse().join("") // 翻转
if(!isPalindrome(self)) { //如果不是回文
if(m.has(self)) { // i 和 num 对称 组成回文
let num = m.get(self)
if(!hasRepeatNum(i, num)) {
group.push([i, num])
}
} else {
m.set(re, i)
}
}
}
}
for(let i = 0 ; i < group.length; i++) {
let a = group[i]
for(let j = i+1; j < group.length; j++) {
let b = group[j]
if(!hasRepeatNum(a.join(""),b.join("")) && lenIs10(a.concat(b))) {
res = res.concat(getIp(group[i], group[j]))
}
}
}
return res
};
findSpecialIP() // ["68.205.179.34", "34.205.179.68", "68.179.205.34", "34.179.205.68"]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。