【问题标题】:Moving list elements with a particular value to end of list将具有特定值的列表元素移动到列表末尾
【发布时间】:2016-06-16 07:08:55
【问题描述】:

我有一个字符串列表,我试图将所有具有特定值的字符串放到列表的末尾。在我编写的代码中,我尝试使用函子和列表排序将所有等于“Hello”的字符串带到列表的末尾。

#include<iostream>
#include<list>
#include<string>
using namespace std;

struct DescendingFunctor
{
private:
    string StructString;

public:
    DescendingFunctor(string S) : StructString(S) {}

    bool operator()(const string& LHS, const string& RHS)
    {
        return LHS > StructString;
    }
};

int main()
{
    list<string> s;
    s.push_back("C++");
    s.push_back("World");
    s.push_back("Hello");
    s.push_back("Hello");
    s.push_back("World");
    s.push_back("C++");

    DescendingFunctor d("Hello");
    s.sort(d);

    return 0;
}

但是,当我尝试使用此代码时,我得到一个无效的比较器错误。我知道这个错误的根源在于表达式 -

return LHS > StructString;

因为当我用

替换它时
return LHS > RHS;

列表按降序排列。有什么办法可以使用 list::sort 将所有等于“Hello”的字符串带到列表的末尾?如果不是,那么实现这一目标的好方法是什么?

【问题讨论】:

  • 据我了解,我将 LHS 和 RHS 作为参数传递,但我只使用其中一个。我认为我的理解是不正确的。你能解释一下原因吗?

标签: c++ list sorting stl


【解决方案1】:

出于多种原因,您应该更喜欢使用std:partition

  1. 正如您所指出的(在评论中),您只使用了二元谓词的参数之一。这使您的二元谓词不一致 - 它并没有真正定义relevant ordering。相反,partition 中的谓词是一元的,您可以在语义上完全按照自己的意愿使用它。

  2. 就复杂性而言,排序对于您的需要来说是多余的,因为复杂性是 Θ(n log(n);相反,partition 的复杂性是线性的。

也许你可以试试这样的:

std::partition(
    std::begin(s),
    std::end(s),
    [](const string &w){return w != "hello";});

【讨论】:

  • 我要解决的实际问题需要我使用列表(我的问题是对问题的简化)。虽然我看到分区在此示例中更合适,但您对如何使用列表实现目标有什么建议吗?
  • @propeeper: std::partition 只需要 ForwardIterators,而 std::list 提供 BidirectionalIterators,所以它应该对列表进行分区,没有任何问题。
【解决方案2】:

试试这个逻辑

bool operator()(const string& LHS, const string& RHS)
{
    return LHS != StructString && RHS == StructString;
}

它给你你想要的。

您收到无效的比较器错误,因为对于某些两个项目 AB 进行比较,运算符返回 true 表示 A 应该先于 B 同时表示B 应该在 A之前。同时返回false并不意味着第二个应该在前。

无论如何,同样的任务可以用更低的时间复杂度来完成,即O(n) 而不是O(n * log(n))

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 2011-06-22
    • 2017-07-10
    • 2014-05-19
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2020-06-09
    相关资源
    最近更新 更多