C数据结构-位运算升级版

leetcode751题,IP 到 CIDR。之前介绍过简单的C数据结构-位运算处理,但是这道题新鲜的东西很多,值得再写一篇。

题目意思就是取IP后联系N个地址,但是表达方法要用CIDR。
真的想不出来真的想不出来真的想不出来,作者太牛了,戳这里看作者题解!
整个神奇的地方有:
1、sscanf可以转字符串为整数,作为初始计算点。
2、对整数取二进制下最后一个1的位置,这个位置如果比n小,那么可以生成一串地址,然后检查与n的关系继续循环。获取二进制下最后一个1的位置方法是x&-x
3、通过sprintf转整数为拼接字符串。
4、申请指针空间居然是ret = (char *)realloc(ret, sizeof(char) * (count + 1));–但是这个函数不够安全

1、字符串转整数处理

unsigned long charToLong(char *ip)
{
    
    
	unsigned long a, b, c, d;
	unsigned long ret;
	sscanf_s(ip, "%lu.%lu.%lu.%lu", &a, &b, &c, &d);
	ret = (a << 24) | (b << 16) | (c << 8) | (d);
	return ret;
}

2、进行功能处理

while (n > 0) {
    
    
		prefix = 0;
		bestlow = iplong & (-1) * iplong;
		while (bestlow > n) {
    
    
			bestlow = bestlow >> 1;
		}
		oneloc = bestlow >> 1;
		while (oneloc) {
    
    
			oneloc = oneloc >> 1;
			prefix++;
		}
		ret = (char **)realloc(ret, sizeof(char*) * (count + 1));
		ret[count] = (char*)malloc(sizeof(char)*IPMAX);
		longToChar(iplong, 32 - prefix, ret[count]);

		n -= bestlow;
		iplong += bestlow;
		count++;

	}

3、字符串转整数

void longToChar(unsigned int iplong, int prefix, char *ret)
{
    
    
	unsigned long a, b, c, d;
	d = iplong & 0xff;
	c = (iplong >> 8) & 0xff;
	b = (iplong >> 16) & 0xff;
	a = (iplong >> 24) & 0xff;
	sprintf_s(ret, IPMAX, "%lu.%lu.%lu.%lu/%d", a, b, c, d, prefix);
	return;

}

猜你喜欢

转载自blog.csdn.net/weixin_45554139/article/details/104868489