• 1000: 恶意IP 课程作业



    1000: 恶意IP

    Time Limit: 1 Sec  Memory Limit: 16 MB

    Description

    Water同学最近好不容易学会了用Tornado建起一个个人的Website,并且成功上线了。

    来访用户逐渐增多,但Water发现总有些恶意用户很喜欢刷屏,总是回复些评论如“楼主不要放弃治疗!”,“楼主药不能停!”之类的。Water感受到了这个世界满满的恶意,他很不爽,决定将这部分恶意用户过滤掉。

    他已经掌握到这些用户的IP了,但是过滤IP这件事情对于数据结构挂了的他来说实在是有些困难,所以他来找你帮忙了!

    IP格式为 a.b.c.d , 其中 a,b,c,d均为[0,255]之间的整数。

    Input

    只有一组数据。第一行为一个整数N [0, 1 000 000],代表恶意IP列表的长度。接下来N行是N个恶意IP。
    然后紧随一个整数M [0, 1 000 000],代表访问IP的长度。接下来M行是M个来访IP。
    你需要判断该来访IP是否在恶意IP列表中。

    Output

    如果来访IP是恶意IP,则输出 FILTER,否则输出 PASS。

    Sample Input

    5
    233.233.233.233
    250.250.250.250
    10.20.30.40
    123.255.123.255
    172.18.182.69
    6
    10.123.128.245
    233.233.233.233
    172.18.182.253
    102.30.40.50
    172.18.182.96
    172.18.182.69
    

    Sample Output

    PASS
    FILTER
    PASS
    PASS
    PASS
    FILTER

    这是我们数据结构的一道题,这道题本来不难,只要时间内存足够一个map就可以了,关键是时间要求1s内存是16MB,并且坑的是,测试数据量1 000 000组。那么这就要讲究策略了。首先不能用c++的STL和输入输出流还有string吧。。这些都是很耗空间和时间的。要效率就得选择C语言了。
    然后是搜索问题,我们要根据字符串来搜索。在这里不管是快排还是归并都是达不到要求的,因为数据量太大。那么要选择什么呢?肯定哈希啦。。
    所以下面就是怎么构造哈希表的问题了。因为键值是字符串不能当数组的下标,而且建数组的话也要注意大小问题。我选择的是BKDRHash函数,因为这个函数还是比较常用的。函数如下:
     1 unsigned int BKDRHash(char *str)
     2 {
     3     unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
     4     unsigned int hash = 0;
     5 
     6     while (*str)
     7     {
     8         hash = hash * seed + (*str++);
     9     }
    10 
    11     return (hash & 0x7FFFFFFF);
    12 }

    这里因为数据量最大是 1 000 000, 那么我们就构建一个 1 000 000 大小的数组吧。然后因为当字符串长的时候 BKDRHash()函数的返回值其实是很大的,所以返回值要对 1 000 000取余。

    还有一个要注意的问题是冲突问题,一般情况下我一般用拉链法。。所以就拉链了。。。

    下面是我的代码实现,因为写得比较急有点挫。。。

     1 #include <iostream>
     2 #include <stdio.h>
     4 #include <string.h>
     5 
     6 using namespace std;
     7 
     8 unsigned int BKDRHash(char *str) {
     9     unsigned int seed = 131;
    10     unsigned int hash = 0;
    11 
    12     while (*str) {
    13         hash = hash * seed + (*str++);
    14     }
    15 
    16     return (hash & 0x7FFFFFFF);
    17 }
    18 
    19 struct Node {
    20     char* value;
    21     Node* next;
    22     //value is link to a list which has conflict elements
    23     Node(char* value_ = NULL){
    24         value = value_;
    25         next = NULL;
    26     }
    27 };
    28 
    29 Node **arr = new Node*[1000001];
    30 
    31 void initializeHash(int N) {
    32     //we can't only use a char[] here because the
    33     //address of str will not change in this way, 
    34     //and the elements will be the same because
    35     //they are just the same element
    36     char* str;
    37     for (int i = 0; i != N; i++) {
    38         str = new char[17];
    39         scanf("%s", str);
    40         unsigned int temp = BKDRHash(str);
    41         temp %= 1000000;
    42 
    43         if (arr[temp] == NULL) {
    44             arr[temp] = new Node(str);
    45         } else {
    46             Node* root = arr[temp];
    47             while (root->next != NULL) {
    48                 root = root->next;
    49             }
    50             root->next = new Node(str);
    51         }
    52     }
    53 }
    54 
    55 void judgeIp(char* str) {
    56     unsigned int temp = BKDRHash(str);
    57         temp %= 1000000;
    58         if (arr[temp] == NULL) {
    59             printf("PASS
    ");
    60         } else {
    61             bool flag = true;
    62             Node* root = arr[temp];
    63             while (root != NULL) {
    64                 if (strcmp((root->value), str) == 0) {
    65                     flag = false;
    66                     printf("FILTER
    ");
    67                     break;
    68                 }    
    69                 root = root->next;
    70             }
    71             if (flag)
    72                printf("PASS
    ");
    73         }
    74 }
    75 int main(int argc, char const *argv[])
    76 {
    77     int N;
    78     scanf("%d", &N);
    79     for (int i = 0; i != 1000001; i++)
    80         arr[i] = NULL;
    81     initializeHash(N);
    82 
    83     char str[17];
    84     scanf("%d", &N);
    85     for (int i = 0; i != N; i++) {        
    86         scanf("%s", str);
    87         judgeIp(str);
    88     }
    89     return 0;
    90 }
     
  • 相关阅读:
    【翻译自mos文章】rman 标准版和企业版的兼容性
    HDU 1010 Tempter of the Bone
    uva 10716 Evil Straw Warts Live(贪心回文串)
    适配器及适配器模式
    Android推送技术研究
    【hadoop2.6.0】倒排索引遇到问题了
    【hadoop2.6.0】MapReduce原理
    【hadoop2.6.0】一句话形容mapreduce
    【leetcode】Median of Two Sorted Arrays(hard)★!!
    【leetcode】Merge k Sorted Lists
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/3443680.html
Copyright © 2020-2023  润新知