題目描述
開發一個簡單錯誤記錄功能小模塊,能夠記錄出錯的代碼所在的文件名稱和行號。
處理:
1.記錄最多8條錯誤記錄,對相同的錯誤記錄(即文件名稱和行號完全匹配)只記錄一條,錯誤計數增加;(文件所在的目錄不同,文件名和行號相同也要合併)
2.超過16個字符的文件名稱,只記錄文件的最後有效16個字符;(如果文件名不同,而只是文件名的後16個字符和行號相同,也不要合併)
3.輸入的文件可能帶路徑,記錄文件名稱不能帶路徑
輸入描述:
一行或多行字符串。每行包括帶路徑文件名稱,行號,以空格隔開。 文件路徑爲windows格式 如:E:\V1R2\product\fpgadrive.c 1325
輸出描述:
將所有的記錄統計並將結果輸出,格式:文件名代碼行數數目,一個空格隔開,如: fpgadrive.c 1325 1 結果根據數目從多到少排序,數目相同的情況下,按照輸入第一次出現順序排序。 如果超過8條記錄,則只輸出前8條記錄. 如果文件名的長度超過16個字符,則只輸出後16個字符
輸入例子1:
E:\V1R2\product\fpgadrive.c 1325
輸出例子1:
fpgadrive.c 1325 1
解決思路
1.記錄最多8條錯誤記錄,對相同的錯誤記錄(即文件名稱和行號完全匹配)只記錄一條,錯誤計數增加;(文件所在的目錄不同,文件名和行號相同也要合併)
2.超過16個字符的文件名稱,只記錄文件的最後有效16個字符;(如果文件名不同,而只是文件名的後16個字符和行號相同,也不要合併)
3.輸入的文件可能帶路徑,記錄文件名稱不能帶路徑
先將所有的字符串存入哈希表,key爲字符串,value爲<出現順序,出現次數>,順序取相同的字符串的最小值,次數一直累加
排序的話,利用set重寫比較器,按次數降序,次數相同則按出現順序排列
插入過程利用hash時間複雜度可以認爲是O(n)
排序過程set的是紅黑樹,可以認爲是O(nlgn) ,總的複雜度就是這個了
代碼如下
#include<iostream>
#include<unordered_map>
#include<set>
#include<string>
#include <fstream>
#include <stdio.h>
using namespace std;
class info
{
public:
int rank;//次序
int count;//次數
string file;//文件名+行號
info(const int _r,const int _c, const string _s):rank(_r),count(_c),file(_s){}
bool operator < (const info& _info)const
{
if(this->count == _info.count)
return this->rank < _info.rank;
return this->count > _info.count;
}
};
int fun(char *x)
{
char *y = x;
while (*y++);
return (y - x - 1);
}
//主程序
int main1()
{
char x[] = {'1','2','3','4'};
int m = fun(x);
string instr,file;
std::set<info> errors;
std::set<info>::iterator iset;
int pos = 0;
int i = 1;
ifstream geoFile;
geoFile.open("text.txt", ios::in);
if (geoFile.is_open())
{
while(getline(geoFile,instr))
{
if(instr.empty()) break;
pos = instr.rfind('\\');
file = instr.substr(pos + 1);
iset = errors.begin();
while(iset != errors.end())
{
if(iset->file == file)
break;
iset++;
}
if(iset == errors.end())
{
errors.insert(info(i++,1,file));
continue;
}
info temp = *iset;
temp.count++;
errors.erase(iset);
errors.insert(temp);
}
}
geoFile.close();
iset = errors.begin();
i = 0;
while(iset != errors.end() && i < 8)
{
file = iset->file;
pos = file.find(' ');
if(pos > 16)
file = file.substr(pos - 16);
cout << file<<" "<<iset->count<<endl;
iset++;
i++;
}
return 0;
}