模拟实现atoi和itoa以及100G 的IP地址求出现次数最多的前K个IP

版权声明:最短的时间最核心的知识,有疑问,欢迎进行留言。 https://blog.csdn.net/lizhidefengzi/article/details/77012072

1.模拟实现C库的atoi和itoa。

2.给一个超过100G的log file, log中存着IP地址, 设计算法找到出现次数最多的100个IP地址?

1.题考察面试者的思维方式:完整性和鲁棒性
先想好测试用例,沟通好错误处理,才能满意的做完。

错误需要考虑的情况有:
1.当字符串为空时返回0,0字符串返回值也是0,但是两者的含义不同,我们应该做到区分,怎么区分? 定义全局变量,设置有效无效
2.“+123”“-565”,
3.数值溢出
4.字符串为NULL
5.穿入非法字符,怎么解决?
6.“+”“-” (+ - 号后面没有跟数字)

enum Status{kValid=0,kInvalid};
int g_nstatus = kValid;


long long strToIntCore(const char* digit,bool minus)
{
    long long num = 0;
    while (*digit)
    {
        if (*digit >= '0'&*digit <= '9')
        {
            int flag = minus ? -1 : 1;
            num = num * 10 + flag*(*digit - '0');
            if (!minus&&num > 0x7FFFFFFF || minus&&num < 0x80000000)
            {
                num = 0;
                break;
            }
        }
        else
        {
            break;
        }

        digit++;

    }
    if (*digit == '\0')
    {
        g_nstatus = kValid;
    }
    return num;
}
int myatoi(const char* str)
{
    g_nstatus = kInvalid;  //(初始化为无效值)
    long long num = 0;
    if (str == NULL || *str != '\0')
    {
        bool minus=false;
        if (*str == '+')
        {
            str++;
            minus = false;
        }
        if (*str == '-')
        {
            str++;
            minus = true;
        }

        if (!*str != '\0')
        {
            num = strToIntCore(str,minus);
        }
    }
    return (int)num;

}

/////////////////////////////////////////////////
char* myitoa(int num,char* str,int radix)
{
    char index[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    unsigned int unum = 0;
    int i = 0;
    if (radix == 10 && *str == '-')
    {
        str[i++] = '-';
    }
    unum = (unsigned)num;

    do 
    {
        str[i++] = index[unum % radix];
        unum = unum / radix;
    } while (unum);
    str[i] = '\0';//字符串\0结尾

    int k = 0;
    //字符串翻转
    if (str[0] == '-')
    {
        k = 1;
    }
    i = i - 1;
    for (k; k <=i;)//基数个元素会相聚到一个元素上, 偶数个元素会错开位置 
    {
        char temp = str[i];
        str[i] = str[k];
        str[k] = temp;
        k++;
        i--;
    }
    return str;
}

2.给一个超过100G的log file, log中存着IP地址, 设计算法找到出现次数最多的100个IP地址?

一般来讲求topK 问题,建堆求topK来解决大数据问题非常有效。
此处来进行求解出现次数最多的IP地址,

首先看到100G的日志文件,我们的第一反应肯定是太大了,根本加载不到内存,更别说设计算法了,那么怎么办呢?既然装不下,我们是不是可以将其切分开来,一小部分一小部分轮流进入内存呢,答案当然是肯定的。

在这里要记住一点:但凡是大数据的问题,都可通过切分来解决它。

粗略算一下:如果我们将其分成1000个小文件,每个文件大概就是500M左右的样子,现在计算机肯定轻轻 松松就能装下。

那么,问题又来了,怎样才能保证相同的IP被分到同一个文件中呢?

这里我想到的是哈希切分,使用相同的散列函数(如 BKDRHash)将所有IP地址转换为一个整数key,再利用 index=key%1000就可将相同IP分到同一个文件。

依次将这1000个文件读入内存,出现次数最多的IP进行统计。

最后,在1000个出现次数最多的IP中找出最大的出现次数即为所求。

用到的散列函数:

与上题条件相同,如何找到TOP K的IP?

答:

这倒题说白了就是找前K个出现次数最多的IP,即降序排列IP出现的次数。

与上题类似,我们用哈希切分对分割的第一个个小文件中出现最多的前K个IP建小堆,

然后读入第二个文件,将其出现次数最多的前K个IP与 堆中数据进行对比,

如果包含大于堆中的IP出现次数,则更新小堆,替换原堆中次数的出现少的数据

再读入第三个文件,以此类推……

直到1000个文件全部读完,堆中出现的K个IP即是出现 次数最多的前K个IP地址。

参考网址大数据:http://www.sohu.com/a/138204769_236714

猜你喜欢

转载自blog.csdn.net/lizhidefengzi/article/details/77012072