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

 

 

 

posted @ 2020-10-31 20:20  __小王子  阅读(200)  评论(0)    收藏  举报