- 论坛徽章:
- 0
|
原帖由 cooper84 于 2009-1-10 11:16 发表 ![]()
谢谢大家 我忘记写另外一个条件了,第三个[]中带00000的不用排序,要删除掉,我举例子中的3-4行记录就要删除
那很好说。在我4楼的半伪代码中,在while循环的一开始,判断一下是否跳过(剔出)就行,后面的逻辑完全不影响。
//-- C++ code
struct RecordItem
{
TimeType time; //-- 你的时间纪录 (方便排序比较的类型,比如将时间转换为毫秒数,然后用uint64_t什么的存一下)
std::string strTime; //-- 你时间的原始记录
std::string desc; //-- 你的第三个[]的内容
void* other;
//-- member function
RecordItem() {}
RecordItem(std::string & strOrgTime, std::string & orgDesc): strTime(strOrgTime), desc(orgDesc)
{
InitTimeTypeDataByString(strOrgTime); //-- 初始化你的 time成员
}
bool operator == ( const RecordItem & r ) {return time == r.time; }
bool operator != ( const RecordItem & r ) {return time != r.time; }
bool operator <= ( const RecordItem & r ) {return time <= r.time; }
bool operator >= ( const RecordItem & r ) {return time >= r.time; }
bool operator < ( const RecordItem & r ) {return time < r.time; }
bool operator > ( const RecordItem & r ) {return time > r.time; }
};
void Sort(record_list)
{
std::set<RecordItem> *foundSet;
std::map<std::string, std::set<RecordItem> > allItem;
RecordItem item;
while(item = record_list.getAnItem()) //-- 假设返回NULL表示结束
{
if(item.desc.find("00000") //-- find只是举例,直接这样用应该不够严密。
continue; //-- 如果遇到你刚才说的条件,那就跳过,直接剔出该条数据。
foundSet = allItem.find(item.desc);
if(foundSet != allItem.end())
{
foundSet->escond.insert(item);
}
else
{
std::set<RecordItem> itemSet;
itemSet.insert(item);
allItem.insert(std::pair<std::string, std::set<RecordItem> >(item.desc, itemSet));
}
}
} |
然后,补充说明一下原理吧。
map,用来将你的数据按照你所说的“第三个[]中记录相同的代表同一条记录”“对同一条记录所耗费的时间进行排序”进行分类。每个类别有一个set。
然后,因为在很多STL的实现中,map和set内部使用的是RB-Tree,而RB_tree是一个有序结构。因此,当我们往set中添加数据后,set内部的RB-tree会使用set实例化的第二个模版参数(在这里我用的是默认参数)less()函数对象,来调用相关的关系操作运算进行操作。而这个操作的副产品就是,当我们从begin()到end()遍历时,就相当于对set内部的rb-tree进行中序遍历,从而导致最终的输出为排序后的有序输出(less()函数对象的话,是从小到大)。这就是为什么在RecordItem中重载了关系运算符的原因了。
而且因为你是要依据时间排序,所以在RecordItem重载关系运算符时,只以time成员为判断依据。同时这也是为什么我在伪代码中建议将时间转换成毫秒数然后存放到64位无符号整型中的原因了,便于比较 + 代码量少。
其实大致代码如上,除了转换函数和剔出判断外,基本上主干代码就如上所示(当然,辅助代码我就不管了,毕竟是示意伪码)。如果需要从大到小排列,反序遍历,或者使用grater()函数对象就行。如果需要其它稀奇古怪的排序方式,写一个函数对象显示地作为set实例化的第二个模版参数,然后适当改一下RecordItem的关系重载实现就行。 |
|