uva1590 IP网络
题目
子网(即连续IP地址范围)可以通过网络地址和子网掩码来描述。子网掩码包含32个二进制位,前32-n位为1,后n位为0;
网络地址的前32-n位是任意的,后n位为0;所有前32- n位和相同的IP地址属于该网络。
例如,网络地址为194.85.160.176(二进制为110,000 10 | 0101 | 101,000 000 | 10110,000)。
子网掩码255.255.255.248(二进制1111111111 | 11111111111 | 11111111111 | 11111000),
则子网IP地址范围从194.85.160.176到194.85.160.183。
输入一些IP地址以查找最小的网络(即包含IP地址最少的网络)包含所有这些输入地址。
代码
#include<stdio.h>
#include<string.h>
//存放用户输入的m个ip,十进制
int ip[1005][4];
//str2存放ip的4*八位二进制形式的副本
char str2[4][9];
//str1放结果的网络地址,mask放结果的子网掩码,均为二进制
char str1[4][9], mask[4][9];
void minAdr(int i)//分析到第i个IP后的网络地址str1,子网掩码mask
{
int flag = 0;
for (int j = 0;j < 4;j++) {
int k = 8, temp = ip[i][j];
while (k--) {
str2[j][k] = temp % 2;
temp = temp >> 1;//注意>>只是一个运算,只有a=a>>1才改变了a的值
}
}//完成str2存放第i个ip的二进制副本
for (int j = 0;j < 4;j++) {
for (int k = 0;k < 8;k++) {
if (!flag)
if (str2[j][k] != str1[j][k]) {
flag = 1;//判断本ip与上一个ip是否一样,flag=1表示出现不同
}
if (flag) {
//i=0,网络地址str1存放第一个输入的ip[0]
//i!=0即分析第二个及往后的ip时,从当前ip与str1不同的地方开始往后str1,mask都是0
if (i)str1[j][k] = mask[j][k] = 0;
else str1[j][k] = str2[j][k];
}
}
}
}
int main()
{
int m;
while (scanf("%d", &m) != EOF) {//输入m个ip,ip[][]的数据为十进制的形式
for (int i = 0;i < m;i++) {
for (int j = 0;j < 4;j++) {
scanf("%d", &ip[i][j]);
getchar();
}
}
for (int i = 0;i < 4;i++) {//设置网络地址和掩码的 4*8位为1
for (int j = 0;j < 8;j++) {
str1[i][j] = mask[i][j] = 1;
}
}
for (int i = 0;i < m;i++) {
minAdr(i);
}
for (int j = 0;j < 4;j++) {
ip[0][j] = ip[1][j] = 0;//前两个ip都赋值为0.0.0.0,ip[0]将放网络地址,ip[1]将放子网掩码,节约空间而已
for (int k = 0;k < 8;k++) {
ip[0][j] += (str1[j][k] << (7 - k));//二进制转十进制,a<<i为a*2^i
ip[1][j] += (mask[j][k] << (7 - k));
}
}
for (int i = 0;i < 2;i++)printf("%d.%d.%d.%d\n", ip[i][0], ip[i][1], ip[i][2], ip[i][3]);
}
return 0;
}

浙公网安备 33010602011771号