我需要对C ++ std::vector<std::string> fileNames
进行排序。 fileNames标记为
YYDDDTTTT_Z_SITE
YY =年份(即2009 = 09,2010 = 10) DDD =一年中的某一天(即1月1日= 001,12月31日= 365) TTTT =一天中的时间(即午夜= 0000,中午= 1200)
ZONE =将是E或W
站点=四个字母的站点名称(即HILL,SAMM)
我需要按以下顺序对字符串进行排序:ZONE,SITE,YY,DDD,TTTT
答案 0 :(得分:7)
将std::sort
与比较功能结合使用。
(链接有一个很好的例子)
答案 1 :(得分:2)
简单的部分:编写排序本身:
// Return true if the first arg is strictly less than the second
bool compareFilenames(const std::string& rhs, const std::string& lhs);
...
std::sort(fileNames.begin(), fileNames.end(), &compareFilenames);
更难的部分:编写比较本身。在伪代码中,为了完全普遍性:
bool compareFilenames(const std::string& lhs, const std::string& rhs)
{
parse the filenames
if (lhs zone != rhs zone)
return lhs zone < rhs zone
if (lhs site != rhs site)
return lhs site < rhs site
...
return false
}
其中lhs site
等是您需要排序的数据的各个位,从文件名中挑选出来。
鉴于您拥有严格的文件命名结构,以及您的特定排序需求,您实际上可以通过第一个'_'字符拆分字符串并对第二个块进行字典比较,然后执行第一个如果第二个块相等,则为chunk。这将使代码更容易解析文件名,如果文件命名格式发生变化,可能会产生灵活的成本。
答案 2 :(得分:1)
只需编写一个方法,根据您的标准比较两个文件名,确定哪一个首先出现,然后使用任何标准排序方法。
答案 3 :(得分:1)
使用std::sort
并实施比较类
答案 4 :(得分:0)
您可以将qsort
与您自己的字符串比较函数一起使用,该函数会考虑您的排序规则,以及每个向量中要求数组的第一个元素的地址。
http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/
但你不应该。只需使用std::sort
答案 5 :(得分:0)
您传递给vector::sort()
的排序谓词可能会创建字符串的重新排序的临时字符串,然后进行比较。
答案 6 :(得分:0)
这是一个提升lambda函数版本。这是过度的,而且非常神秘,但它在如何处理不同的字段标准方面简洁而灵活。显然你需要提升。此外,期望增加编译时间。所以,这是:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/detail/control_structures_impl.hpp"
#include "boost/ref.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <cassert>
using namespace std;
using namespace boost::lambda;
//helpers: a better way would be to group them
//under a flyweight, or something...
string extract_year(string str_)
{
return str_.substr(0,2);
}
string extract_dayofyear(string str_)
{
return str_.substr(2,3);
}
string extract_timeofday(string str_)
{
return str_.substr(5,4);
}
string extract_zone(string str_)
{
return str_.substr(10,1);
}
string extract_site(string str_)
{
return str_.substr(12,4);
}
//Uhm, just for brevity... ('cause otherwise we should stay away from macros ;-)
#define IF_THEN_ELSE_RET(op1,op2,exp) if_then_else_return(var(op1)<var(op2),true,if_then_else_return(var(op1)>var(op2),false,exp))
void sort_fnames(vector<string>& fnames)
{
string z1,z2,s1,s2,y1,y2,d1,d2,t1,t2;
//sort by zone-then-site-then-year-then-day-then-time:
//Note the format of the sort(fnames.begin(),fnames.end(), (,...,boolean_expression) );
//remember, in a sequence of comma-dellimited statements enclosed between parens, like
//val=(.,...,boolean_expression); only the last expression, boolean_expression, gets
//assigned to variable "val";
//So, in the sort() call below, the statements
//var(z1)=bind(extract_zone,_1),var(z2)=bind(extract_zone,_2), etc.
//are only initializing variables that are to be used in the composition
//of if_then_else_return(,,) lambda expressions whose composition
//combines the zone-then-site-then-year-then-day-then-time criteria
//and amounts to a boolean that is used by sort to decide the ordering
sort(fnames.begin(),fnames.end(),
(var(z1)=bind(extract_zone,_1),var(z2)=bind(extract_zone,_2),
var(s1)=bind(extract_site,_1),var(s2)=bind(extract_site,_2),
var(y1)=bind(extract_year,_1),var(y2)=bind(extract_year,_2),
var(d1)=bind(extract_dayofyear,_1),var(d2)=bind(extract_dayofyear,_2),
var(t1)=bind(extract_timeofday,_1),var(t2)=bind(extract_timeofday,_2),
IF_THEN_ELSE_RET(z1,z2,IF_THEN_ELSE_RET(s1,s2,IF_THEN_ELSE_RET(y1,y2,IF_THEN_ELSE_RET(d1,d2,IF_THEN_ELSE_RET(t1,t2,true)))))
));
}