题目的主要信息:

  • ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成一个长整数。
  • 需要完成ip和整数之间的相互转换。

方法一:位运算

ip地址转整数:由原理知,ip地址的每一段都是一个整数,将每四段整数提取出来拼在一起就是长整数。每一段都有八位,因此在拼接的时候,第一段需要向左位移24位,第二段向左位移16位,第三段位移8位,第四段不用位移。需要注意的是,整个过程是无符号的。

整数转ip地址:ip地址的每一段是8位二进制数,因此整数转转ip地址时,向左位移24位,最后剩下的八位即为ip地址的第一段;向左位移16位,低八位为ip地址第二段;向左位移8位,低八位为ip地址第三段;不用位移,低八位为ip地址第四段。 alt 具体做法:

#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;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),只需要进行位运算,消耗常数时间。
  • 空间复杂度:O(1)O(1),只用了常数空间存储变量。

方法二:

以"."为界分割出四个字符串,首先对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;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),for循环多为15次,因为ip地址有格式和大小限制。
  • 空间复杂度:O(1)O(1),只用了常数空间存储变量。