$$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Self-defined math definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Math symbol commands \newcommand{\intd}{\,{\rm d}} % Symbol 'd' used in integration, such as 'dx' \newcommand{\diff}{{\rm d}} % Symbol 'd' used in differentiation ... $$

C语言:IPv6地址压缩

题目

IPv6 二进位制下为 128 位长度,以 16 位为一组,每组以冒号“:”隔开,可以分为 8组,每组以 4 位十六进制方式表示。
例如:2001:0db8:0000:0000:0123:4567:89ab:cdef 是一个合法的 IPv6 地址。

同时 IPv6 地址在某些条件下可以压缩:
 1、每组数字代表的独立 16 进制数可以省略前位的 0。
 例如上面的 IPv6 地址可被压缩为:2001:db8:0:0:123:4567:89ab:cdef

 2、可以用双冒号“::”表示一组 0 或多组连续的 0,但只能出现一次。
 例如上面的 IPv6 地址可被压缩为:2001:db8::123:4567:89ab:cdef

规则补充:
 1、输入数据为完全展开的 IPv6 地址,确保输入的 IPv6 地址不含双冒号,每组地址省略的 0 都会被补充上去。

 2、双冒号只能使用一次,因此我们压缩最长的全 0 组
 比如:2001:0db8:0000:0000:1:0000:0000:0000
 我们压缩为 2001:db8:0:0:1:: 而非 2001:db8::1:0:0:0

 3、双冒号只能只用一次,因此我们在我们遇到地址中多个连续全 0 组长度相同时,我们压缩最前面的一个。
 比如:2001:0db8:0000:0000:ffff:0000:0000:1
 压缩为 2001:db8::ffff:0:0:1,而非 2001:db8:0:0:ffff::1

 4、输入的 IPv6 地址可能无法被压缩,因此请照原样输出


代码


#include<stdio.h> 

int main(){
	int a[10];
	int i,start,end;
	int max[3]={0,0,0},len=0;
	
	scanf("%x:%x:%x:%x:%x:%x:%x:%x",
		&a[1],&a[2],&a[3],&a[4],&a[5],&a[6],&a[7],&a[8]);
	a[0]=1;a[9]=1; 
	for(i=0;i<10;i++){
		if(a[i]==0){
			if(a[i-1]!=0){
				len = 1;
				start = i;
			}
			else{
				len += 1;
				end = i;
			}
		}
		else{
			if(len>max[0]){
				max[0] = len;
				max[1] = start;
				max[2] = end;
				len = 0; 
			}
		}
	}
	if(max[1]==1)printf(":");
	for(i=1;i<9;i++){
		if(i<max[1])printf("%x:",a[i]);
		if(i>max[2])printf(":%x",a[i]);
	}
	if(max[2]==8)printf(":");
	return 0;
}
posted @ 2022-11-18 12:05  Shin404  阅读(1472)  评论(0)    收藏  举报