题目的主要信息:
- ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成一个长整数。
- 需要完成ip和整数之间的相互转换。
方法一:位运算
ip地址转整数:由原理知,ip地址的每一段都是一个整数,将每四段整数提取出来拼在一起就是长整数。每一段都有八位,因此在拼接的时候,第一段需要向左位移24位,第二段向左位移16位,第三段位移8位,第四段不用位移。需要注意的是,整个过程是无符号的。
整数转ip地址:ip地址的每一段是8位二进制数,因此整数转转ip地址时,向左位移24位,最后剩下的八位即为ip地址的第一段;向左位移16位,低八位为ip地址第二段;向左位移8位,低八位为ip地址第三段;不用位移,低八位为ip地址第四段。 具体做法:
#include<iostream>
#include<string>
using namespace std;
int main(){
unsigned int a0,a1,a2,a3;//用来保存ip地址的四个数字
char s1,s2,s3;//用来保存'.'
long num;//需要转IP地址的长整数
while(cin>>a3>>s3>>a2>>s2>>a1>>s1>>a0>>num){
long o1=a3<<24|a2<<16|a1<<8|a0; //ip地址转长整数
cout<<o1<<endl;
cout<<(num>>24)<<'.'<<((num>>16)&0xff)<<'.'<<((num>>8)&0xff)<<'.'<<(num&0xff)<<endl;//长整数转ip地址
}
return 0;
}
复杂度分析:
- 时间复杂度:,只需要进行位运算,消耗常数时间。
- 空间复杂度:,只用了常数空间存储变量。
方法二:
以"."为界分割出四个字符串,首先对IP地址的每一段字符串进行转换,从string转为十进制数字,再将四段数字拼接起来,拼接的时候需要主要每一段摆放的位置,因此需要借助位移操作。
具体做法:
#include<iostream>
#include<string>
using namespace std;
int main(){
string str;//IP地址
long num;//需要转IP地址的长整数
while(cin>>str>>num){
long res[4] = {0};
for(int i=0,j=0;i<str.size();i++){ //遍历字符串
if(str[i]!='.'){//计算每一段ip的十进制数字
res[j]=res[j]*10+str[i]-'0';
}else{
j++;
}
}
long ans=(res[0]<<24)|(res[1]<<16)|(res[2]<<8)|res[3];//拼接结果
cout<<ans<<endl;
cout<<(num>>24)<<'.'<<((num>>16)&0xff)<<'.'<<((num>>8)&0xff)<<'.'<<(num&0xff)<<endl;//长整数转ip地址
}
return 0;
}
复杂度分析:
- 时间复杂度:,for循环多为15次,因为ip地址有格式和大小限制。
- 空间复杂度:,只用了常数空间存储变量。