c++对排序的日期进行二分搜索 ->我需要一个范围(cca)
我对文件进行二分搜索。该文件充满日志消息,其中每行以日期开头(日期或根据事件发生排序)
示例:
- 2011-09-18 09.38.20.123
- 2011-09-18 09.38.20.245
- 2011-09-18 09.38.20.393
- 2011 -09-18 09.38.20.400
- 2011-09-18 09.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-18 09.38.20.245 (多比少好)
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
}
I have a binary search on a file. The file is filled with log messages where each line begins with a date (dates or sorted based on event occurs)
example:
- 2011-09-18 09.38.20.123
- 2011-09-18 09.38.20.245
- 2011-09-18 09.38.20.393
- 2011-09-18 09.38.20.400
- 2011-09-18 09.38.20.785
If i need to find this date for example: 2011-09-18 09.38.20.390 my binary search will not find an exact match - but i don't need exact match, i need to find the closest date to it (there is my position).
The current code will jump between 2011-09-18 09.38.20.245 and 2011-09-18 09.38.20.393.
I need some help how to modify the below code so that i get the closest number. In the above situation i would like to have: 2011-09-18 09.38.20.245 (better more than less)
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
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试实现相当于
std::equal_range
的算法它返回一对std::lower_bound
和std::upper_bound
--
完整示例:http://ideone.com/CvIYm
Try to implement an algorithm equivalent to
std::equal_range
which returns a pair of result ofstd::lower_bound
andstd::upper_bound
--
Full example: http://ideone.com/CvIYm