华为2016年校园招聘上机笔试题(2)----简单错误记录
2016-04-30 14:48
375 查看
转载请注明出处</article/7845874.html>
问题:
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
输入的文件可能带路径,记录文件名称不能带路径
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325
输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
输入例子:
E:\V1R2\product\fpgadrive.c 1325
输出例子:
fpgadrive.c 1325 1
转载请注明出处</article/7845874.html>
问题:
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
输入的文件可能带路径,记录文件名称不能带路径
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325
输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
输入例子:
E:\V1R2\product\fpgadrive.c 1325
输出例子:
fpgadrive.c 1325 1
方法一:使用关联容器
源代码://先将所有的字符串存入哈希表,key为字符串,value为<出现顺序,出现次数>,顺序取相同的字符串的最小值,次数一直累加 //排序的话,利用set重写比较器,按次数降序,次数相同则按出现顺序排列 //插入过程利用hash时间复杂度可以认为是O(n) //排序过程set的是红黑树,可以认为是O(nlgn) ,总的复杂度就是这个了 #include<iostream> #include<unordered_map> #include<set> #include<string> #include<utility> using std::cout; using std::endl; using std::cin; using std::string; using std::unordered_map; using std::set; using std::pair; struct info{//记录出现的顺序,和次数 int rank; //rank代表出现的顺序 int count; //count代表出现的次数 info(int rank, int count){ this->rank = rank; this->count = count; } }; struct fullinfo{//一条完整的结果,字符串和次数 string file; //记录输入的字符串和行号 int rank; int count; fullinfo(string file, int rank, int count){ this->file = file; this->rank = rank; this->count = count; } }; struct classcomp {//set的比较器 bool operator()(const struct fullinfo& f1, const struct fullinfo& f2){ if (f1.count == f2.count) return f1.rank<f2.rank; //判断f1出现的顺序是否比f2出现的顺序要早 return f1.count>f2.count; //判断f1出现的次数是否比f2出现的次数要多 } }; typedef struct info INFO; typedef struct fullinfo FULLINFO; int main(){ unordered_map<string, INFO> record; //关键字是字符串和行号,值是该关键字的信息包括出现的顺序和次数 unordered_map<string, INFO>::iterator it; unordered_map<string, INFO>::const_iterator itfind; set<FULLINFO, classcomp> ret; //存储处理后的数据,key为字符串、出现的顺序和次数,排序准则用自己定义的结构体 set<FULLINFO, classcomp>::iterator sit; string linestr;//一行输入 //一条记录是由文件名和行号一起决定的,文件名和行号不用拆分开。 string file;//文件名+行号 int pos;//空格的位置 int i = 1; while (getline(cin, linestr)){ if (linestr.length() == 0) break; pos = linestr.rfind("\\"); file = linestr.substr(pos + 1);//拆分得到最后的filename和count //const_iterator find(const Key& keyval) const;函数声明 itfind = record.find(file);//在map中查看是否已经有了该字符串,没有则插入,有则次数加1 if (itfind == record.end()){ INFO tmpi(i, 1); record.insert(pair<string, INFO>(file, tmpi)); } else{ INFO tmpi(itfind->second.rank, itfind->second.count + 1); record.erase(file); //删除掉旧的数据,插入新的数据 record.insert(pair<string, INFO>(file, tmpi)); } i++; } for (it = record.begin(); it != record.end(); it++){ FULLINFO tmpfull(it->first, it->second.rank, it->second.count);//构建排序的set集合 ret.insert(tmpfull); } /* 文件名和行号之间有空格,找出空格的位置,如果空格的位置小于16,说明空格之前文件名的长度肯定小于16,可以直接输出; 如果空格的位置大于16,那说明文件名长度大于16,找到空格的位置向前移动16位,截断字符串输出,就可以保证只输出文件名的后16位。 */ for (i = 0, sit = ret.begin(); sit != ret.end() && i<8; ++sit, ++i){//最多输出8条记录,file少于16位 if (file.find(" ") <= 16){ cout << (*sit).file << " " << (*sit).count << endl; } else{ cout << (*sit).file.substr(file.find(" ") - 16) << " " << (*sit).count << endl; } } return 0; }
方法二:使用有顺序的容器vector
#include<iostream> #include<vector> #include<string> #include<cctype> using std::cout; using std::endl; using std::cin; using std::string; using std::vector; using std::swap; //对字符串中的顺序按条件进行排序 void Process(vector<string> &record, vector<int> &count) { int sz = count.size(); for (int i = 0; i < sz; i++) { if (1 == count[i]) continue; else { for (int j = 1; j < sz - i; j++) { if (count[j - 1] < count[j]) { swap(count[j-1], count[j]); swap(record[j-1], record[j]); } } } } } //向字符串容器和计数容器中读取数据 void readLine(vector<string> &record, vector<int> &count, string &str) { while (getline(cin, str)) { if (str.length() == 0) //如果为空串,则输入结束 break; string lineValid;//输入行中有效的内容,包括文件名和行号 string fileName;//每一行的文件名 auto pos = str.rfind("\\");//获取最后一个转义字符的位置,方便截取输入字符串 lineValid = str.substr(pos + 1); auto pos2 = lineValid.rfind(" ");//获取空格的位置,方便截取文件名 fileName = lineValid.substr(0, pos2); if (fileName.length() > 16)//处理文件名,使之小于等于16个字符 { fileName = fileName.substr(fileName.length() - 16, 16);//处理后的文件名 lineValid = fileName + lineValid.substr(lineValid.find(" "));//处理后的文件名和行号 } if (record.empty())//如果容器时空的话,也就是第一次输入,要将第一行字符串的有效字符输入到容器中 { record.push_back(lineValid); count.push_back(1); } else//如果容器不为空,则依次比较该容器中的内容是否和输入的内容相同,若相同,计数器加1,否则,将该数据加入的容器中,相应的计数器要加1 { int flag = 0; //标志位,判断是否有相同输入行 for (int i = 0; i < record.size(); i++) { if (record[i] == lineValid) { count[i]++; flag = 1; } }//如果没有与容器中的数据相等的输入,则将该行加入到容器中,并使其计数器加1 if (0 == flag) { record.push_back(lineValid); count.push_back(1); } } } } //输出函数 void Print(const vector<string> record, const vector<int> count) { int sz = count.size(); if (sz > 8) sz = 8; for (int i = 0; i < 8; i++) cout << record[i] << " " << count[i] << endl; } int main() { vector<string> record;//记录下所有的有效输入,vector不会出现map中按字典排序的情况,输入的顺序是什么则存储的顺序就是什么 vector<int> count;//记录每行输入的数据出现的次数 string str;//读取每一行输入数据 readLine(record, count, str); Process(record, count); Print(record, count); vector<string>().swap(record); vector<int>().swap(count); return 0; }
转载请注明出处</article/7845874.html>
相关文章推荐
- maven生命周期(转)
- DevicePolicyManager类的使用
- Maven2和MyEclipse插件
- [UVa 11426] GCD - Extreme (II) (数论 + 脑洞 + 技巧)
- 十、森林与并查集---(6)并查集路径压缩优化
- Unity3d生命周期
- JDK7文件处理
- empty与isset的用法及区别(转载)
- 怎样高效阅读源码?
- C - How Many Tables——HOJ
- 【LeetCode】Excel Sheet Column Number 解题报告
- linux设置可以在当前目录查找可执行文件的方法
- 负载均衡的基本算法
- 百度地图 API 使用
- 父子窗口之间的调用
- 自定义可拖拽的view
- Android群英传笔记——第十章:Android性能优化
- 向有序的环形单链表中插入新节点
- Android群英传笔记——第十章:Android性能优化
- ZeroMQ (Martin Sustrik)读后感和笔记