Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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::sort_C++_String_Sorting_Predicate_Strcmp - Fatal编程技术网

C++ 重用字符串比较结果以加快std::sort

C++ 重用字符串比较结果以加快std::sort,c++,string,sorting,predicate,strcmp,C++,String,Sorting,Predicate,Strcmp,我想用strcmp对唯一字符串的向量进行排序 std::sort需要一个谓词来告诉一个字符串是否小于另一个字符串,但是strcmp实际上已经返回了字符串之间的关系,因此明智的做法是使用该信息,而不是丢失它 这很有用,因为它还需要确定字符串是否相等——在这种情况下,谓词将使用相同的字符串再次调用,但参数顺序相反 这是一种简单的排序方式: vector<const char*> cache; sort(cache.begin(), cache.end(), [](const char*

我想用
strcmp
对唯一字符串的向量进行排序

std::sort
需要一个谓词来告诉一个字符串是否小于另一个字符串,但是
strcmp
实际上已经返回了字符串之间的关系,因此明智的做法是使用该信息,而不是丢失它

这很有用,因为它还需要确定字符串是否相等——在这种情况下,谓词将使用相同的字符串再次调用,但参数顺序相反

这是一种简单的排序方式:

vector<const char*> cache;
sort(cache.begin(), cache.end(), [](const char* left, const char* right)
{
    return strcmp(left, right) < 0;
});
向量缓存;
排序(cache.begin(),cache.end(),[](常量字符*左,常量字符*右)
{
返回strcmp(左、右)<0;
});
我正在尝试以下想法,在这里我存储比较的结果,如果再次比较相同的字符串,则重用它

vector<const char*> cache;
sort(cache.begin(), cache.end(), [notLess = false, r = (const char*)nullptr](const char* left, const char* right) mutable
{
    // possibly reuse previous comparison of same strings passed in inverse order
    if (notLess &&
        r == left)
    {
        notLess = false;
        // always less since vector contains unique strings
        return true;
    }

    if (notLess = strcmp(left, right) >= 0)
        r = right;
    return !notLess;
});
向量缓存;
排序(cache.begin(),cache.end(),[notLess=false,r=(const char*)nullptr](const char*左,const char*右)可变
{
//可能会重用以前以相反顺序传递的相同字符串的比较
如果(不小于&&
r==左)
{
notLess=假;
//由于向量包含唯一的字符串,所以总是较少
返回true;
}
如果(不小于等于strcmp(左、右)>=0)
r=右;
回来吧!不;
});
为了限制存储的信息和额外引入的比较的数量,我考虑只存储右字符串,它将成为反向比较的左字符串


现在,我真正的问题是,只检查先前的右字符串是否足够,还是需要存储并检查先前的左字符串?

首先,您的假设是错误的
std::sort
不会使用相同的参数调用比较两次。因此,整个想法是有缺陷的


第二(也是更重要的)您的想法是有缺陷的,因为谓词不应该保存状态
std::sort
可以复制这些谓词并重用副本(事实上,当我前段时间检查时,gcc版本肯定复制了谓词),因此将破坏整个比较。

是的,在这里提出的情况下,由于
sort
不需要区分确切的等价性,这种想法没有什么用处——它可以毫无痛苦地将
a>b
a==b
情况混合在一起(这要感谢等价元素的未指定顺序)

<>但是,如果我们考虑<代码> Stable排序> <代码>,这个想法<强>做< /强>工作。稳定排序实际上需要区分所有三种情况:
a
a==b
a>b
,因此它将调用
Cmp
functor两次

一般来说,处理此类优化通常是合理的,在某些情况下,这是绝对必要的,以避免计算时间呈指数级增长(例如,如果您需要在知道上层比较结果之前搜索子层时对某个多级容器进行排序/搜索)


此外,存储字符串比较的结果可能对后续的排序/搜索/插入操作有用。当然,为了有效地实现这一点,需要一个不需要字符串迭代的快速随机访问容器(否则它在运行时的复杂性将比单纯的strcmp更差)。如果您的字符串首先被规范化,这可能成为可能

标准库可以复制谓词任意次数。“另外还需要确定字符串是否相等”。你是说
std::sort
需要确定这一点吗?不会。在这种情况下,谓词将使用相同的字符串再次调用,但参数顺序相反。-据我所知,这只在
std::sort
的调试运行时实现中完成,其中运行时正在检查谓词是否遵循严格的弱顺序。否则,您无法猜测谓词中将包含哪两项。@HenriMenke
qsort
std::sort
相比是基本的,并且通常较慢。它使用三方比较的能力并没有给它带来任何优势。如果太空船运营商是这样的话,可能会添加更快的
std::sort
。您的说法不正确:std::sort在VS 2017发布的STL实现中使用分区快速排序,并且使用双向比较。第二,复制有状态谓词时没有发生任何非法行为。存储状态的变量仅在可能的情况下用于优化。我的问题是关于只检查一个字符串来检测双向比较是否安全,或者是否需要检查两个字符串