fork(1) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5.  
  6. struct IP
  7. {
  8. char ip[20];
  9. int cidr;
  10. unsigned long mask;
  11. unsigned long binary;
  12. };
  13. void ip_init(struct IP *ip, const char *format);
  14. unsigned long ip_to_long(const int ip[4]);
  15. int ip_sort_by_format(const void *e1, const void *e2);
  16. int ip_sort_by_cidr(const void *e1, const void *e2);
  17. void strip(char *input);
  18. int main(void)
  19. {
  20. int N;
  21. scanf("%d\n", &N);
  22. struct IP ips[N];
  23. int cur = 0;
  24. for(int i = 0; i < N; i++)
  25. {
  26. char line[20];
  27. fgets(line, 20, stdin);
  28. strip(line);
  29. ip_init(&ips[cur], line);
  30. cur++;
  31. }
  32.  
  33. qsort(ips, cur, sizeof(struct IP), ip_sort_by_format);
  34. for(int i = 0; i < cur; i++)
  35. {
  36. for(int j = 0; j < cur; j++)
  37. {
  38. if(i == j)
  39. continue;
  40. if(strcmp(ips[i].ip, "_") == 0)
  41. continue;
  42. if(strcmp(ips[j].ip, "_") == 0)
  43. continue;
  44.  
  45. int small = ips[i].cidr < ips[j].cidr ? i : j;
  46. unsigned long masks[2] = {
  47. ips[i].binary & ips[small].mask,
  48. ips[j].binary & ips[small].mask
  49. };
  50.  
  51. if(masks[0] == masks[1])
  52. strcpy(ips[j].ip, "_");
  53. }
  54. }
  55.  
  56. qsort(ips, cur, sizeof(struct IP), ip_sort_by_cidr);
  57. for(int i = 0; i < cur; i++)
  58. if(strcmp(ips[i].ip, "_") != 0)
  59. printf("%s\n", ips[i].ip);
  60. printf("\n");
  61.  
  62. return 0;
  63. }
  64.  
  65. void ip_init(struct IP *ip, const char *format)
  66. {
  67. int parts[4];
  68. int cidr;
  69. sscanf(format, "%d.%d.%d.%d/%d", &parts[0], &parts[1], &parts[2], &parts[3], &cidr);
  70.  
  71. ip->cidr = cidr;
  72. ip->binary = ip_to_long(parts);
  73. ip->mask = ~(1 << (cidr + 1)) << (32 - cidr);
  74. strcpy(ip->ip, format);
  75. }
  76.  
  77. unsigned long ip_to_long(const int ip[4])
  78. {
  79. return ip[3] | ip[2] << 8 | ip[1] << 16 | ip[0] << 24;
  80. }
  81.  
  82. void strip(char *input)
  83. {
  84. char *eol = strrchr(input, '\n');
  85. if(eol != NULL)
  86. *eol = '\0';
  87. }
  88.  
  89. int ip_sort_by_format(const void *e1, const void *e2)
  90. {
  91. struct IP *ip1 = (struct IP *) e1;
  92. struct IP *ip2 = (struct IP *) e2;
  93.  
  94. int diff = (ip1->binary & ip1->mask) - (ip2->binary & ip2->mask);
  95. if(diff == 0)
  96. return ip1->cidr < ip2->cidr;
  97. return diff;
  98. }
  99.  
  100. int ip_sort_by_cidr(const void *e1, const void *e2)
  101. {
  102. struct IP *ip1 = (struct IP *) e1;
  103. struct IP *ip2 = (struct IP *) e2;
  104. return ip1->cidr - ip2->cidr;
  105. }
Success #stdin #stdout 0s 9432KB
stdin
13
	192.168.0.0/16
	172.24.96.17/32
	172.50.137.225/32
	202.139.219.192/32
	172.24.68.0/24
	192.183.125.71/32
	201.45.111.138/32
	192.168.59.211/32
	192.168.26.13/32
	172.24.0.0/17
	172.24.5.1/32
	172.24.68.37/32
	172.24.168.32/32
stdout
192.168.0.0/16
	172.24.0.0/17
	172.50.137.225/32
	192.183.125.71/32
	201.45.111.138/32
	202.139.219.192/32