C++ c++;排序日期的二进制搜索->;我需要一个范围(cca)
我对一个文件进行了二进制搜索。该文件充满日志消息,其中每行以日期开头(日期或根据事件发生排序) 例如:C++ c++;排序日期的二进制搜索->;我需要一个范围(cca),c++,qt,binary-search,C++,Qt,Binary Search,我对一个文件进行了二进制搜索。该文件充满日志消息,其中每行以日期开头(日期或根据事件发生排序) 例如: 2011-09-18 09.38.20.123 2011-09-1809.38.20.245 2011-09-1809.38.20.393 2011-09-1809.38.20.400 2011-09-1809.38.20.785 如果我需要查找此日期,例如:2011-09-18 09.38.20.390,我的二进制搜索将无法找到精确的匹配-但我不需要精确的匹配,我需要查找最接近的日期(这
- 2011-09-18 09.38.20.123
- 2011-09-1809.38.20.245
- 2011-09-1809.38.20.393
- 2011-09-1809.38.20.400
- 2011-09-1809.38.20.785
BinarySearch::BinarySearch(QString strFileName、QDateTime dtFrom_目标、QDateTime dtTo_目标)
{
QFile文件(strFileName);
qint64 nFileSize=file.size();
int nNewFromPos;
内特纳托波斯;
nNewFromPos=搜索(文件、dtFrom\U目标、nFileSize);
nNewToPos=搜索(文件、dtFrom_目标、nFileSize);
如果(nNewFromPos!=-1&&nNewToPos!=-1){
//现在解析新范围
}
否则{
//出界日期
}
}
int-BinarySearch::Search(QFile&file,QDateTime-dtKey,int-nMax)
{
open(QIODevice::ReadOnly);
字符行缓冲区[1024];
qint64线路长度;
QDateTime dtMid;
int mid;
int-min;
如果(!min)min=0;
while(最小dtMid){
最小值=中间值+1;
}
否则如果(dtKey
尝试实现一种算法,该算法相当于返回一对and结果
模板
无效读取日志范围(
std::istream&logStream,Log::Date from,Log::Date to,OutIter out)
{
Log l=LowerBound(logStream,from);
*out++=l;
while(logStream>>l&&l.date
完整示例:我不明白。如果
mid
恰好与行的开头不一致,这怎么可能工作?您好,readLine函数一直读取到\n,然后我从行的开头读取足够的字符,以便在lineBuffer中具有时间戳。从那里我转换成dateTime对象并使用>,好的,我现在看到它是如何工作的了。但是您仍然在进行基于字节的二进制搜索,因此在找到最近的记录后,您将继续在该记录(或以前的记录)中不必要地搜索其确切的字节偏移量,不是吗?嗨,我不确定“不必要的”和“确切的字节偏移量”是什么意思,但想法是这样的:在我的logViewer应用程序中,当用户执行File->Open时,他可以选择使用DateFrom&Date to(关注用户感兴趣的时间间隔),或者他可以解析整个文件。我在日志文件中对用户选择的DateFrom和DateTo进行2次二进制搜索,以查找最接近或相等(几乎不匹配)的匹配项。在此之后,我缩小了我的范围,我将把这些位置传递给我的主解析方法,然后它将解析以新位置开始和结束的文件。所以二进制搜索只缩小了线性解析的范围——对于CCA130MB的文件,这大约需要一分钟的时间
BinarySearch::BinarySearch(QString strFileName,QDateTime dtFrom_target,QDateTime dtTo_target)
{
QFile file(strFileName);
qint64 nFileSize = file.size();
int nNewFromPos;
int nNewToPos;
nNewFromPos = Search(file, dtFrom_target, nFileSize);
nNewToPos = Search(file, dtFrom_target, nFileSize);
if(nNewFromPos!=-1 && nNewToPos!=-1){
// now parse the new range
}
else{
// dates out of bound
}
}
int BinarySearch::Search(QFile &file, QDateTime dtKey, int nMax)
{
file.open(QIODevice::ReadOnly);
char lineBuffer[1024];
qint64 lineLength;
QDateTime dtMid;
int mid;
int min;
if(!min) min = 0;
while (min <= nMax)
{
mid=(min+nMax)/2; // compute mid point.
file.seek(mid); // seek to middle of file (position based on bytes)
qint64 lineLength=file.readLine(lineBuffer,sizeof(lineBuffer)); // read until \n or error
if (lineLength != -1) //something is read
{
// validate string begin (pos = 0) starts with date
lineLength = file.readLine(lineBuffer, 24); //read exactly enough chars for the date from the beginning of the log file
if(lineLength == 23)
{
dtMid = QDateTime::fromString(QString(lineBuffer),"yyyy-MM-dd HH.mm.ss.zzz"); //2011-09-15 09.38.20.192
if(dtMid.isValid())
{
if(dtKey > dtMid){
min = mid + 1;
}
else if(dtKey < dtMid){
max = mid - 1; // repeat search in bottom half.
}
else{
return mid; // found it. return position
}
}
}
}
}
return -1; // failed to find key
}
template<typename OutIter>
void ReadLogsInRange(
std::istream& logStream, Log::Date from, Log::Date to, OutIter out)
{
Log l = LowerBound(logStream, from);
*out++ = l;
while(logStream >> l && l.date < to)
*out++ = l;
}