Bootstrap

华为杯——D IPv6

互联网协议第六版 (IPv6) 是被设计用于替代 IPv4 的新一代互联网协议。相比 IPv4,IPv6 最大的特点是,IPv6 大幅扩大了地址空间,能够有效解决 IPv4 地址紧张的情况。  

  IPv6 地址由 128 位二进制数构成,这 128 位二进制数被分成 8 组,每组 16 位。用冒号 分隔法表示 IPv6 地址的方式如下:   

  xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx  

  其中,xxxx 是 4 位十六进制数,代表地址中一组,其中十六进制数中的字母既可以大写 也可以小写。此外,如果某组十六进制数中有多余的前导 0,那么这些多余的前导 0 可以省 略不写。例如,以下是一个 IPv6 地址的示例:  

  abcd:1234:aCA9:123:4567:089:0:0000  

  为了进一步简化书写,有时还会采用 0 位压缩表示法,即如果有一个或多个连续的全 0 组,那么可以将这些连续的全 0 组删去,替换成两个冒号 ‘::’;如果替换的结果中含有多于两 个连续冒号,则将多余的冒号删去直至只有两个连续的冒号。需要注意的是,在同一个 IPv6 地址中,0 位压缩表示最多只能使用 1 次。例如,以下均为合法的带 0 位压缩表示的 IPv6 地 址:   

  7abc::00ff:fffc 表示 7abc:0:0:0:0:0:ff:fffc 

  FC::8976:0000:0000:0000:00ff 表示 fc:0:0:8976:0:0:0:ff 

  2c0f:9981:: 表示 2c0f:9981:0:0:0:0:0:0 

  :: 表示 0:0:0:0:0:0:0:0   

  现在,给你一些可能带 0 位压缩表示的 IPv6 地址,你需要将他们转换成完整形式。具体 地说,你需要依次完成以下任务:  

  1. 恢复被压缩的全 0 组; 

  2. 补齐被省略的前导 0,直至每组都是 4 位十六进制数; 

  3. 将所有英文字母转换为小写字母。 例如,上面提到的 5 个 IPv6 地址,它们对应的完整表示分别为  

  abcd:1234:aca9:0123:4567:0089:0000:0000  

  7abc:0000:0000:0000:0000:0000:00ff:fffc  

  00fc:0000:0000:8976:0000:0000:0000:00ff  

  2c0f:9981:0000:0000:0000:0000:0000:0000  

  0000:0000:0000:0000:0000:0000:0000:0000  

 

输入描述:

第一行包含一个整数 T (1 ≤ T ≤ 200),表示测试用例的组数。
接下来 T 行,每行一个字符串,表示一个可能带 0 位压缩表示的 IPv6 地址。
保证输入一定是合法的可能带 0 位压缩表示的 IPv6 地址。

输出描述:

依次输出每个 IPv6 地址对应的完整表示。每个地址占一行。

样例输入:

复制

5
abcd:1234:aCA9:123:4567:089:0:0000
7abc::00ff:fffc
FC::8976:0000:0000:0000:00ff
2c0f:9981::
::

样例输出:

abcd:1234:aca9:0123:4567:0089:0000:0000
7abc:0000:0000:0000:0000:0000:00ff:fffc
00fc:0000:0000:8976:0000:0000:0000:00ff
2c0f:9981:0000:0000:0000:0000:0000:0000
0000:0000:0000:0000:0000:0000:0000:0000

提示:

 

来源:

南阳理工学院第四届程序设计竞赛A组(南京大学出题)

坑点:有可能出现8个冒号的样例如下:

::1234:aca9:0123:4567:0089:0000:0000
或
abcd:1234:aca9:0123:4567:0089:0000::
这样死wa

题解如下:大模拟

#include<iostream>
#include<cstring>
using namespace std;
char a[1000009],g[1000009];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(g,0,sizeof(g));
		scanf("%s",&a);
		int dd=strlen(a);int h1=-1,h2=0;
		for(int i=0;i<dd-1;++i)
		{
			if(a[i] == ':' && a[i+1] == ':')
			{
				h1=i;
			}	
		}
		for(int i=0;i<dd;++i)
		{
			if(a[i] == ':')
			{
				h2++;
			}	
		}
		int g6=h2;int h3=7-h2;int h4=0;	int g1=0,g2=0;
		for(int i=0;i<dd;++i)
			{
				if(i == h1)
				{
					while(h3--)
					{
						if(h3<0)
						{
							break;
						}
						g[h4]=':';
						h4++;
					}
				}
				g[h4]=a[i];
				h4++;
			}
		if(g6 == 8)
		{
			if(a[0] == ':' && a[1] == ':')
			{
				printf("0000:");g1=2;
				for(int i=2;i<h4;++i)
				{
					if(g[i] == ':')
					{
						int z1=4-(i-g1);
						for(int j=0;j<z1;j++)
						{
							printf("0");
						}
						for(int j=g1;j<i;j++)
						{
							if('A'<=g[j] && g[j]<='Z')
							{
								g[j]+=('a'-'A');
								printf("%c",g[j]);
							}
							else{
								printf("%c",g[j]);
							}
						}
						g1=i+1;
						printf(":");
					}
				}	
			}
			else{
				for(int i=0;i<h4-1;++i)
				{
					if(g[i] == ':')
					{
						int z1=4-(i-g1);
						for(int j=0;j<z1;j++)
						{
							printf("0");
						}
						for(int j=g1;j<i;j++)
						{
							if('A'<=g[j] && g[j]<='Z')
							{
								g[j]+=('a'-'A');
								printf("%c",g[j]);
							}
							else{
								printf("%c",g[j]);
							}
						}
						g1=i+1;
						printf(":");
					}
				}
				g1++;
			}
		}
	else
	{
			
	//	for(int i=0;i<h4;++i)
	//	{
	//		printf("%c",g[i]);
	//	}
	//	printf("\n");
		for(int i=0;i<h4;++i)
		{
			if(g[i] == ':')
			{
				int z1=4-(i-g1);
				for(int j=0;j<z1;j++)
				{
					printf("0");
				}
				for(int j=g1;j<i;j++)
				{
					if('A'<=g[j] && g[j]<='Z')
					{
						g[j]+=('a'-'A');
						printf("%c",g[j]);
					}
					else{
						printf("%c",g[j]);
					}
				}
				g1=i+1;
				printf(":");
			}
		}	
	}
		int g3=4-(h4-g1);
		while(g3--)
		{
			printf("0");
		}
		for(int i = g1;i<h4;i++)
		{
			if('A'<=g[i] && g[i]<='Z')
			{
				g[i]+=('a'-'A');
				printf("%c",g[i]);
			}
			else{
			printf("%c",g[i]);	
			} 
		}
		printf("\n");
	}
	
	return 0;
}

 

;