[C++] 简单错误记录
输入采用了std::getline来输入整行,采用istringstream流来分解文件名和行号,采用vector<tuple>来存储记录元素。
分解并简化文件名采用的是find_last_of来分割子串,查找数组中可能有重复的记录采用find_if来实现,其中谓词函数采用lambda表达式实现,原因是普通的谓词函数只能是一元或者是二元,而本题中组内tuple元素,局部参数url和line_str共三个参数,所以采用lambda捕获两个局部变量。而如果查找存在则直接+1,不存在则采用emplace新增一个tuple元素,为什么不采用push_back呢,哈哈因为push_back采用的是拷贝构造,而emplace采用的是移动构造,当有大量记录时,效率会高很多。
#include<iostream> #include<sstream> #include<string> #include<vector> #include<algorithm> #include<tuple> using namespace std; int main() { string s; vector<tuple<string, string, int>> vt; //分别表示文件名,行号和数量 // 读取每一行记录 while(getline(cin, s)){ // 分解文件名和行号 istringstream iss(s); string total_url,line_str; getline(iss, total_url, ' '); getline(iss, line_str); string url = total_url.substr(total_url.find_last_of('\\')+1); if (url.size() > 16){ url = url.substr(url.size()-16, 16); } vector<tuple<string,string, int>>::iterator it = find_if(vt.begin(), vt.end(), [url,line_str](const tuple<string,string, int> &r)->bool { return (std::get<0>(r) == url && std::get<1>(r) == line_str); } ); if(it != vt.end()){ get<2>(*it) += 1; } else{ vt.emplace(it, url, line_str, 1); } } // 输出最新的8个记录 if( vt.size() > 8){ for(int i = vt.size() -8; i < vt.size(); ++i){ cout<< get<0>(vt[i]) <<" "<< get<1>(vt[i]) <<" "<< get<2>(vt[i]) <<" "<<endl; } } else{ for(int i = 0; i < vt.size(); ++i){ cout<< get<0>(vt[i]) <<" "<< get<1>(vt[i]) <<" "<< get<2>(vt[i]) <<" "<<endl; } } return 0; }