IP(4)地址与十进制之间的相互转换
IP(4)地址的格式为 n1.n2.n3.n4 ,其中n1到n4表示的是8位二进制数值转换十进制后的数值,为此IP(4)地址的范围为 0.0.0.0 -- 255.255.255.255,即二进制表示为全0和全1时对应的十进制数值。
IP(4)地址转换为十进制
根据题目的意思,将一个IP(4)地址的每段区间的十进制数值用二进制表示,再将这些二进制数按原来的高低位有序排列,组合的二进制数再转换为最终的十进制数值。
举例:一个ip地址为10.0.3.193
每段数字 相对应的二进制数
10 00001010
0 00000000
3 00000011
193 11000001
组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。
所以,一个直观的解法就是十进制转换为二进制,然后二进制再转换为十进制。
然而,我们会发现该小问本质是十进制转换为十进制的问题。只不过前者是每段的十进制数值,它们会有不同的位权。后者是这些前者按权相加的结果。

所以我们只需要得到每区间的十进制数值,再按权相加即可。权值从高到低位为2^24,2^16,2^8,2^0,因为每个区间对应于高24-31二进制位,高16-23二进制位,高8-15二进制位,高0-7二进制位。取每个区间最低位为位权。
cin>>s1;
int i=0,j=0;//双指针用来截取各区间的十进制数值
string tem;
int n=24;//位权起始值
long long sum=0;//n用来得到阶码,sum最终为二进制转换十进制后的数值
s1+='.';//方便截取各区间的十进制数值
while(s1[j]){
if(j==s1.size())break;
if(s1[j]=='.'){
tem=s1.substr(i,j-1-i+1);//截取各区间的十进制数值
sum+= atoi(tem.c_str()) * pow(2,n) ;//sum保留最后结果
n=n-8;i=j+1;
}
j++;
}
cout<<sum<<endl;
十进制转换为IP(4)地址
本小问的十进制是各区间的十进制数值的按权相加之和。由于都是十进制,所以总和十进制 N=n1*2^24+n2*2^16+n3*2^8+n4*2^0
用简单的除法(得到商)和减法(令当前区间为最高位)即可。
long long ne=s2;
int n1,n2,n3,n4;
n1=ne/(pow(2,24));
ne=ne-n1*pow(2,24);
cout<<n1<<'.';
n2=ne/(pow(2,16));
ne=ne-n2*pow(2,16);
cout<<n2<<'.';
n3=ne/(pow(2,8));
ne=ne-n3*pow(2,8);
cout<<n3<<'.';
n4=ne;
cout<<n4;
总代码
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
int main(){
string s1;
long long s2;
cin>>s1>>s2;
int i=0,j=0;
string tem;
int n=24;
long long sum=0;//n用来得到阶码,sum最终为二进制转换十进制后的数值
s1+='.';
while(s1[j]){
if(j==s1.size())break;
if(s1[j]=='.'){
tem=s1.substr(i,j-1-i+1);
sum+= atoi(tem.c_str()) * pow(2,n) ;//
n=n-8;i=j+1;
}
j++;
}
cout<<sum<<endl;
long long ne=s2;
int n1,n2,n3,n4;
n1=ne/(pow(2,24));
ne=ne-n1*pow(2,24);
cout<<n1<<'.';
n2=ne/(pow(2,16));
ne=ne-n2*pow(2,16);
cout<<n2<<'.';
n3=ne/(pow(2,8));
ne=ne-n3*pow(2,8);
cout<<n3<<'.';
n4=ne;
cout<<n4;
return 0;
}