题目
给定一个字符串数组,其中每条内容为一个操作日志,形式为:
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 {};
}