互联网协议第六版 (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;
}