IP地址排序、IP区段去重

原创 2012年03月29日 23:11:39
1. 请问如何对这样一组IP地址排序?
95.243.188.67
102.107.11.122
93.131.2.17
95.243.188.67
96.96.12.138
100.181.237.106
223.155.40.25


method1:

#include <stdio.h>
#include <stdlib.h>

typedef int BYTE ;

typedef struct _IP {
 	BYTE seg[4];
 	struct _IP *next;
}IP;

int main()
{
 	int i, found;
 	IP *pip, *ptem, *pfind;
 	BYTE tem_ip[4];
 	
 	// 循环链表尾指针
 	pip = (IP *)malloc(sizeof(IP));
 	pip->next = pip;

 	printf("Input IP address like:\n192.168.1.11\n10.10.128.11\n......\nInput '0.0.0.0' to end input\n");
 	while (1) 
 	{
  		scanf("%d.%d.%d.%d", &tem_ip[0], &tem_ip[1], &tem_ip[2], &tem_ip[3]);
  		if (!(tem_ip[0] || tem_ip[1] || tem_ip[2] || tem_ip[3]))
   			break;
  		ptem = (IP *)malloc(sizeof(IP));
  		for (i = 0; i < 4; i++)
   			ptem->seg[i] = tem_ip[i];

  		found = 0;
  		pfind = pip;
  		while (pfind->next != pip) 
  		{
	   		for (i = 0; i < 4; i++) 
	   		{
	    		if (ptem->seg[i] < pfind->next->seg[i]) 
	    		{
	     			found = 1;
	     			break;
	    		} 
	    		else if (ptem->seg[i] > pfind->next->seg[i]) 
	    		{
	     			break;
	    		}
	   		}
	   		if (found)
	    		break;
	   		pfind = pfind->next;
  		}

  		ptem->next = pfind->next;
  		pfind->next = ptem;
	}

 	printf("\nSorted ip address:\n");
 	ptem = pip->next;
 	while (ptem != pip) {
 	 	printf("%d.%d.%d.%d\n", ptem->seg[0], ptem->seg[1], ptem->seg[2], ptem->seg[3]);
  		ptem = ptem->next;
 	}
 	return 0;
}


method2:

 /*
  使用C++标准库的快速排序函数
  C++的标准库stdlib.h中提供了快速排序函数。
  请在使用前加入对stdlib.h的引用:#include <cstdlib> 或 #include <stdlib.h>
  qsort(void* base, size_t num, size_t width, int(*)compare(const void* elem1, const void* elem2))
  参数表
  *base: 待排序的元素(数组,下标0起)。
  num: 元素的数量。
  width: 每个元素的内存空间大小(以字节为单位)。可用sizeof()测得。
  int(*)compare: 指向一个比较函数。*elem1 *elem2: 指向待比较的数据。
  比较函数的返回值
  返回值是int类型,确定elem1与elem2的相对位置。
  elem1在elem2右侧返回正数,elem1在elem2左侧返回负数。
  控制返回值可以确定升序/降序。
  一个升序排序的例程:
  */
#include <stdio.h>
#include <stdlib.h>


#if 0 
int Compare(const void *elem1, const void *elem2) 
{ 
	return *((int *)(elem1)) - *((int *)(elem2));
} 
int main()
{
	int i;
	int a[10]= {5, 1 ,2,6,1,2,5,7,8,9};
	qsort(a, 10, sizeof(int), Compare); 
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}
#endif



typedef struct _IP {
 	int seg[4];
}IP;

int Compare(const void *elem1, const void *elem2) 
{ 
	int i;
	IP *ptem1 = (IP*)elem1;
	IP *ptem2 = (IP*)elem2;
	
	for (i = 0; i < 4; i++) 
	{
		if (ptem1->seg[i] < ptem2->seg[i]) 
		{
	 		return -1;
		} 
		else if (ptem1->seg[i] > ptem2->seg[i]) 
		{
	 		return 1;
		}
	}
	return 0;
} 
int main()
{
	int i;
	IP a[4]= {{5, 1 ,2,6},{1,2,5,7},{8,9,0,9},{1,2,3,4}};
	qsort(a, 4, sizeof(IP), Compare); 
 	for (i = 0; i < 4; i++)
 	 	printf("%d.%d.%d.%d\n", a[i].seg[0], a[i].seg[1], a[i].seg[2], a[i].seg[3]);
}

2. 题目:IP段格式:ip1 ip2。之间以空格分开,ip形式为X.X.X.X,数据保存在文件中,文件不超过2k行,无序。现在要求编写算法去掉可重IP,可重有三种形式:包含、交叠、紧靠。


例如,文件内容为:


10.0.0.0 10.0.0.12
10.0.0.5 10.0.0.10 (<= 包含)
10.0.0.8 10.0.0.15 (<= 交叠)
10.0.0.15 10.0.0.24 (<= 紧靠)

最后输出为:10.0.0.0 10.0.0.24


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int BYTE ;

typedef struct _IP {
 	BYTE ip1[4];
 	BYTE ip2[4];
 	struct _IP *next;
}IP;

void Print(IP* ptem)
{	
printf("%d.%d.%d.%d %d.%d.%d.%d\n", ptem->ip1[0], ptem->ip1[1], ptem->ip1[2], ptem->ip1[3], ptem->ip2[0], ptem->ip2[1], ptem->ip2[2], ptem->ip2[3]);
}

void Print_IP(IP* pip)
{
	IP* ptem = pip->next;
 	while (ptem != pip) {
 		Print(ptem);
  		ptem = ptem->next;
 	}
 	
}

int compare(const void *elem1, const void *elem2) 
{ 
	int i, ret = 0;
	BYTE *ptem1 = (BYTE*)elem1;
	BYTE *ptem2 = (BYTE*)elem2;
	
	for (i = 0; i < 4; i++) 
	{
		if (ptem1[i] < ptem2[i]) 
		{
	 		return -1;
		} 
		else if (ptem1[i] > ptem2[i]) 
		{
	 		return  1;
		}
	}
	return 0;
} 


int IpRelation(IP *p1, IP *p2)
{
	int ret = 2;			// 间隔
	switch (compare(p2->ip1, p1->ip2))
	{
		case 1:
			if (p1->ip2[3] + 1 ==  p2->ip1[3])
				ret = 1; 	// 相邻
			break;
		case 0:
			ret = 3;	 	// 紧靠
			break;
		case -1:
			if (compare(p2->ip2, p1->ip2) == 1)
				ret = 4; 	// 交叠
			else
				ret = 5;	// 包含

	}
	return ret;
}

int main()
{
 	int 	i;
 	IP 		*pip, *ptem, *pfind, *qtem;
	FILE*	fp;

	fp = fopen("ip.txt","r");
	if (fp == NULL)
	{
		printf("ip.txt");
		printf("doesn't exist\n");
		fclose(fp);
		return -1;
	}
 	
 	pip = (IP *)malloc(sizeof(IP));
 	pip->next = pip;
	
 	printf("read ip1:ip2 from file.\n");
 	while (1) 
 	{
 		ptem = (IP *)malloc(sizeof(IP));
  		if (fscanf(fp, "%d.%d.%d.%d %d.%d.%d.%d", &ptem->ip1[0], &ptem->ip1[1], &ptem->ip1[2], &ptem->ip1[3], &ptem->ip2[0], &ptem->ip2[1], &ptem->ip2[2], &ptem->ip2[3]) == EOF)
  		{
  			free(ptem);
  			ptem = NULL;
   			break;
   		}
  		pfind = pip;
  		while (pfind->next != pip) 
  		{
	   		if (-1 == compare(ptem->ip1, pfind->next->ip1))
	    		break;
	   		pfind = pfind->next;
  		}

  		ptem->next = pfind->next;
  		pfind->next = ptem;
	}
	
	fclose(fp);
	
 	printf("\nSorted ip address:\n");
	Print_IP(pip);
 	
 
 	ptem = pip->next;
 	
 	while (ptem->next != pip) 
 	{
 	
 		qtem = ptem->next;
 		switch (IpRelation(ptem, qtem))
 		{
 			case 2: 
 					ptem = ptem->next;
 					break;
 			case 1:
 			case 3:
 			case 4:
 					/* ;如果存在交叠、相邻或紧靠,更新上一行的节点,删除当前行节点 */
 					memcpy(ptem->ip2, qtem->ip2, sizeof(BYTE)*4);
 					ptem->next = qtem->next;
 					free(qtem);
 					break;
 			case 5:
 					ptem->next = qtem->next;
 					free(qtem);

 		}
	}
	
 	printf("\n ip address seg:\n");
	Print_IP(pip);
 	return 0;
}


相关文章推荐

如何对IP地址进行排序?

Q:在A2:A8单元格中存储的IP地址,点升序按钮后结果并不能依次按照4个地址段的大小进行排序,如何解决? A:方法一、使用辅助列在B2输入公式如下,然后对B列进行排序: =SUMPRODUCT(MI...
  • grj2007
  • grj2007
  • 2015年06月01日 22:11
  • 467

第一篇博客:将用户程序转为系统程序

第一篇博客:将用户程序转为系统程序时光飞逝,大三因为喜欢玩手机软件开始接触安卓,到现在即将毕业,自己也在试用期中,觉得是时候慢慢把学到的,用到的东西记录下来,也方便以后项目需要用到进行查找,第一篇来讲...

Java-编程之美-中国象棋

解决该问题的关键是将棋盘进行抽象化成一个数据表,这样对数据表的操作便于对棋盘的操作。本题采用的抽象化是将它看成是两个9点阵,如下所示:     *  1  2    3     *  4  5    ...

查询IP所在区段

  • 2007年05月19日 20:38
  • 13KB
  • 下载

python对ip地址进行排序

  • 2015年02月02日 14:37
  • 10KB
  • 下载

黑马程序员_Java基础_正则表达式,校验QQ号,手机号,邮箱,IP地址排序,网络爬虫

一,正则表达式 概述:符合一定规则的表达式。用于专门用于操作字符串的。虽然字符串中有很多字符串的操作方法,但是使用起来比较繁琐,而且代码量比较多。 特点:用一些特定的符号表示以一些代码操作,简化...

IP地址排序问题

题目:把以下IP存入一个txt文件,编写程序把这些IP按数值大小,从小到大排序并打印处理啊。 61.54.231.245 61.54.231.9 61.54.231.246 61.54.231.4...

IP地址排序

题目:把以下IP存入一个txt文件,编写程序把这些IP按数值大小,从小到达排序并打印出来。 61.54.231.245 61.54.231.9 61.54.231.246 61.54.231.48 6...

10亿个IP地址排序、10亿年龄排序

(一). 注意:IPV4 的IP地址2^32位约42亿个,占空间4G (二).哈希函数 1.哈希函数即散列函数 哈希函数的输入域可以是非常大的范围,但是输出域是固定范围。 2.哈希函数的性质...

不重起Windows直接更改IP地址

注:本文适用于WINDOWS NT/2000/XP/2003 下载本文示例工程 源代码运行效果图如下:   设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重新...
  • bbdxf
  • bbdxf
  • 2012年05月09日 09:10
  • 794
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IP地址排序、IP区段去重
举报原因:
原因补充:

(最多只允许输入30个字)