Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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++ 不使用默认算法对字符串的std向量排序_C++_Sorting_Std - Fatal编程技术网

C++ 不使用默认算法对字符串的std向量排序

C++ 不使用默认算法对字符串的std向量排序,c++,sorting,std,C++,Sorting,Std,我有一个std::vector的std::strings,每个字符串都是一个文件名。假设文件名的格式为some\u name\n.xyz 问题是somename\u10.xyz小于somename\u2.xyz。这些文件是由其他过程生成的 最简单的排序方法是什么,这样就可以考虑比较“_”后面的数字,而不仅仅是长度 最简单的方法是将适当的前导零放在文件名中(甚至编写第二个脚本来接受生成的名称并重命名它们可能比编写自己的排序例程更容易) 第二种最不痛苦的方法是编写自己的排序谓词,将分隔的数字作为数字

我有一个
std::vector
std::strings
,每个字符串都是一个文件名。假设文件名的格式为
some\u name\n.xyz

问题是
somename\u10.xyz
小于
somename\u2.xyz
。这些文件是由其他过程生成的


最简单的排序方法是什么,这样就可以考虑比较“_”后面的数字,而不仅仅是长度

最简单的方法是将适当的前导零放在文件名中(甚至编写第二个脚本来接受生成的名称并重命名它们可能比编写自己的排序例程更容易)


第二种最不痛苦的方法是编写自己的排序谓词,将分隔的数字作为数字排序,而不是按字典进行排序。

std::sort
允许您指定用于比较两个元素的二进制函数:


现在只需要构造那个二元函数。部分示例如下:

这里有一个比较,用于处理嵌入字符串中的任意数量的数值:

#include <cstdlib>
#include <cctype>
#include <iostream>

#ifdef  _MSC_VER
#define strtoll _strtoi64
#endif

int cmp(const char* lhs, const char* rhs)
{
    while (*lhs || *rhs)
    {
        if (isdigit(*lhs) && isdigit(*rhs))
        {
            char* l_end;
            char* r_end;
            long long l = strtoll(lhs, &l_end, 10);
            long long r = strtoll(rhs, &r_end, 10);
            if (l < r) return -1;
            if (l > r) return 1;
            lhs = l_end;
            rhs = r_end;
        }
        else
            if (*lhs != *rhs)
                return *lhs - *rhs;
            else
                ++lhs, ++rhs;
    }
    return *lhs - *rhs;
}
#包括
#包括
#包括
#ifdef硕士学位
#定义strtoll\u strtoi64
#恩迪夫
int cmp(常量字符*lhs,常量字符*rhs)
{
而(*lhs | |*rhs)
{
if(isdigit(*lhs)和isdigit(*rhs))
{
char*l_end;
字符*r_结束;
长l=strtoll(左端和左端,10);
长r=strtoll(右端和右端,10);
如果(lr)返回1;
lhs=l_端;
rhs=r_端;
}
其他的
如果(*lhs!=*rhs)
返回*lhs-*rhs;
其他的
++左,右;
}
返回*lhs-*rhs;
}
它故意采用“C风格”,因此可以直接有效地应用于字符数组。如果
lhs
,则返回负数;如果它们相等,则返回0;如果
lhs>rhs
,则返回正数


您可以从指定为
std::sort

的比较函子或lambda调用此函数。您可以使用如下自定义比较器:

struct Comp{

    auto get_num (const std::string& a)
    {
        auto it1 = std::find_if( a.begin(), a.end(), ::isdigit );
        auto it2 = std::find_if( a.begin(), a.end(), 
                               [](char x){ return x == '.' ;}) ;
        /* Do some checks here for std::string::npos*/
        auto pos1 = std::distance( a.begin(), it1) ;
        auto pos2 = std::distance( it1, it2) ;
        return std::stoi (a.substr( pos1, pos2 )) ;
    }

    bool operator () (const std::string& a, const std::string& b)
    {
        return get_num (a) < get_num (b) ;
    }

};
struct Comp{
自动获取数量(常量std::string&a)
{
auto it1=std::find_if(a.begin(),a.end(),::isdigit);
auto it2=std::find_if(a.begin(),a.end(),
[](char x){return x='.';});
/*在这里检查std::string::npos*/
auto pos1=std::distance(a.begin(),it1);
自动定位2=标准::距离(it1,it2);
返回std::stoi(a.substr(pos1,pos2));
}
布尔运算符()(常量std::string&a,常量std::string&b)
{
返回getnum(a)

请参阅演示

您可以简单地将它们重命名为类似于
“\uu%04d”
。编写您自己的comparator functor并将其传递给sort?为什么不使用默认算法
?什么
默认算法
?请查看以下答案以供参考。@Manu343726:这根本不是重复的。。。它需要一个正常的