算法学习日记——日活跃度和月活跃度统计

题目

给定一个字符串数组,其中每条内容为一个操作日志,形式为:

year-month-day|ip地址|operation|state,例如:
2020-02-01|192.168.218.218|/login.do|success

已知,给定的一组输入均为同一个月内的操作日志,ip地址每组数忽略前置0,即192.0.01.02等价于192.0.1.2,数组并未按日期排列。
现规定日(月)活跃度为:不同IP每日(月)内进行"/login.do"操作,且状态为"success"的次数。
请返回给定操作日志数组的月活跃度和日活跃度。

思路

本题核心是统计每天和每月,不同IP成功login.do的次数。那么,这个“不同”就可以利用set来完成,因为set具有去重功能,只需建立一个月set和31个日set,然后将当月(日)所有成功login,do的ip放入月(日)set。
思路有了,接下来还有个问题,需要对每个IP进行处理,将他们化为统一的格式,即去除多余的前缀0。
再然后,由于所有日志均属于同一个月,因此有效信息仅为“日”信息。

代码

字符串分解函数

获取日期及IP地址的每段信息,并根据指定字符ch,将其转化为字符串数组

vector<string> getCom(string s, char ch){
        int i=0, j=0, n=s.size();
        vector<string> res;
        while(i<n){
            while(i<n && s[i]==ch){
                i++;
            }
            j=i;
            while(j<n && s[j]!=ch){
                j++;
            }
            string temp = s.substr(i, j-i);
            res.push_back(temp);
            i=j;
        }
        return res;
    }

IP地址统一函数

string transfer(string s){
        int n = s.size();
        vector<string> ipStrs = getCom(s, '.');
        string res = "";
        for(auto s : ipStrs){
            string temp = to_string(stoi(s));
            res += temp;
            res += ".";
        }
        return res.substr(0, res.size()-1);
    }

核心函数

vector<int> GetActiveUserNum(const vector<string> &logs)
    {
        set<string> month; // 月set
        vector<set<string>> day(31); //日set
        for(auto s : logs){
            vector<string> strs = getCom(s, '|');
           for(int i=0;i<strs.size();i++){
               if(i==0){
                   strs[i] = strs[i].substr(strs[i].size()-2,2);
               }else if(i==1){
                   strs[i] = transfer(strs[i]);
               }
           }
           if(strs[2] == "/login.do" && strs[3] == "success"){
               month.insert(strs[1]);
               day[stoi(strs[0])-1].insert(strs[1]);
           }
        }
        cout << month.size() << " ";
        for(int i=0;i<day.size();i++){
            cout << day[i].size();
            if(i!=day.size()-1){
                cout << " ";
            }
        }
        return {};
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值