Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;排序日期的二进制搜索->;我需要一个范围(cca)_C++_Qt_Binary Search - Fatal编程技术网

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
如果我需要查找此日期,例如:2011-09-18 09.38.20.390,我的二进制搜索将无法找到精确的匹配-但我不需要精确的匹配,我需要查找最接近的日期(这是我的位置)

当前代码将在2011-09-18 09.38.20.245和2011-09-18 09.38.20.393之间跳转

我需要一些帮助如何修改下面的代码,以便我得到最接近的数字。在上述情况下,我想要的是:2011-09-1809.38.20.245(好于少)

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;
    }