開發一個簡單錯誤記錄功能小模塊,能夠記錄出錯的代碼所在的文件名稱和行號。
處理:
1.記錄最多8條錯誤記錄,對相同的錯誤記錄(即文件名稱和行號完全匹配)只記錄一條,錯誤計數增加;(文件所在的目錄不同,文件名和行號相同也要合併)
2.超過16個字符的文件名稱,只記錄文件的最後有效16個字符;(如果文件名不同,而只是文件名的後16個字符和行號相同,也不要合併)
3.輸入的文件可能帶路徑,記錄文件名稱不能帶路徑
輸入描述:
一行或多行字符串。每行包括帶路徑文件名稱,行號,以空格隔開。
文件路徑爲windows格式
如:E:\V1R2\product\fpgadrive.c 1325
輸出描述:
將所有的記錄統計並將結果輸出,格式:文件名代碼行數數目,一個空格隔開,如: fpgadrive.c 1325 1
結果根據數目從多到少排序,數目相同的情況下,按照輸入第一次出現順序排序。
如果超過8條記錄,則只輸出前8條記錄.
如果文件名的長度超過16個字符,則只輸出後16個字符
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <tuple>
using namespace std;
bool compare(tuple<string, int> a, tuple<string, int> b){
return get<1>(a) > get<1>(b);
}
int main() {
string str;
vector<tuple<string, int> > v;
while (getline(cin, str)){
int nameBeg = 0;
auto rit = find(str.rbegin(), str.rend(), '\\');
string::iterator it((++rit).base());
nameBeg = it - begin(str) + 1;
string name_line = string(begin(str) + nameBeg, end(str));
int i = 0;
for (; i != v.size(); ++i) {
if (name_line == get<0>(v[i])) {
++get<1>(v[i]);
break;
}
}
if (i == v.size())
v.emplace_back(make_tuple(name_line, 1));
}
int len = min(8, static_cast<int>(v.size()));
for (int i = 0; i < len; ++i) {
stable_sort(v.begin(), v.end(), compare);
int id = get<0>(v[i]).find(' ');
if (id > 16)
get<0>(v[i]) = string(begin(get<0>(v[i])) + id - 16, end(get<0>(v[i])));
cout << get<0>(v[i]) << " " << get<1>(v[i]) << endl;
}
return 0;
}
第一次寫的結果 60%通過, 有錯
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str;
vector<string> name_lines;
vector<int> numErrs;
while (getline(cin, str)){
int nameBeg = 0;
int nameEnd = 0;
for (int i = 0; i != str.size(); ++i) {
if (str[i] == '\\')
nameBeg = i + 1;
else if (str[i] == ' ') {
break;
}
}
string name_line = string(begin(str) + nameBeg, end(str));
auto it = find(begin(name_lines), end(name_lines), name_line);
if (it == end(name_lines)) {
name_lines.emplace_back(name_line);
numErrs.emplace_back(1);
} else {
++numErrs[it - begin(name_lines)];
}
}
int len = min(8, static_cast<int>(name_lines.size()));
for (int i = 0; i < len; ++i) {
for (int j = numErrs.size() - 1; j - 1 >= i; --j) {
if (numErrs[j] > numErrs[j - 1]) {
swap(numErrs[j], numErrs[j - 1]);
swap(name_lines[j], name_lines[j - 1]);
}
}
// 錯誤在這裏,當 k > 16 時 name_lines[i]被修改, 然後
// 沒有break, 導致 k != name_lines[i].size() 成立,
// 溢出, 如果k < name_lines[i].size() 的話也就是多循環
// 一次但不會報錯。
for (int k = 0; k != name_lines[i].size(); ++k) {
if (name_lines[i][k] == ' ') {
if (k <= 16) break;
name_lines[i] = string(begin(name_lines[i]) + k - 16, end(name_lines[i]));
}
}
cout << name_lines[i] << " " << numErrs[i] << endl;
}
}