使用自定义排序对向量进行排序

Posted

技术标签:

【中文标题】使用自定义排序对向量进行排序【英文标题】:Sort Vector with custom sort 【发布时间】:2017-07-04 21:25:17 【问题描述】:

这适用于具有 A.num>B.num 的 cmp 函数,但小于它为所有值输出零,我知道为什么谢谢。我想知道我在调用函数时是否做错了什么?

#include <bits/stdc++.h>
using namespace std;

typedef struct node

    int num;
Node;

这会在 A.num 时出错

bool cmpNode(Node A,Node B)
    return A.num<=B.num;


int main()

    int n;
    cin>>n;

    //std::vector<char> v;
    vector<Node> vec(n);

    for (int i = 0; i < n; ++i)
    
        Node temp;//    =new Node;
        cin>>temp.num;
        vec.push_back(temp);

    

    sort(vec.begin(), vec.end(),cmpNode);

    for (int i = 0; i < n; ++i)
    
        cout<<vec[i].num<<" ";
    
    return 0;

【问题讨论】:

不要这样做:#include &lt;bits/stdc++.h&gt; - 它不便携,也不聪明。 一个错误?你做错了什么。 &lt;= 不满足std::sort 的要求。 你的比较函数不正确。查找严格的弱顺序。如果AB 相等怎么办?哪一个先于另一个?现在看到问题了吗?此外,在 C++ 程序中不需要 typedef struct —— 只需 struct 即可。 除了比较函数的错误,看看你用push_back做了什么。你的向量已经是n 元素,但你却在推回更多。这显然是错误的。 【参考方案1】:

让我们检查每个错误:

问题 1:

您正在对已调整大小为 n 条目的向量调用 push_back。因此,在输入循环中,您只是在vector 的末尾添加更多项目,从而增加了它的大小。

更正应该如下:

vector<Node> vec;

问题 2:

std::sort 的比较函数需要 严格的弱顺序。换句话说,当给定两个项目时,您的函数必须唯一声明哪个项目在排序顺序中排在第一位,如果第一个项目在第二个项目之前,则返回true,否则返回false

您的比较函数违反了这一点,因为如果A == B 则返回true,如果B == A 则再次返回true。那么ABB 之前是在A 之前吗?

当然,如果向量中有重复项,这将无法正常工作,并且会完全放弃排序算法(这是 Visual C++ 调试运行时检查是否有有效的比较函数 - 比较函数被调用两次并检查两次调用的返回值)。

更正应该如下:

bool cmpNode(const Node& A, const Node& B)
    return A.num < B.num;

还要注意按引用而不是按值传递的用法。

【讨论】:

谢谢,主要问题是我之前已经初始化了向量中的“n”值,而在排序时,我得到的是 0 以升序排列……我真的需要问一下,如果我通过值或引用传递节点? 如果您按值传递,您将创建Node 的临时副本。如果Node 是一个昂贵的复制对象,那么您可能会减慢您的程序速度。此外,您还有两个“主要”问题。第一个是向量,但我在答案中指出的第二个不仅是另一个主要问题,如果你不知道它就很难检测到。如果您的向量包含重复项,那么您的程序将在排序上表现出未定义的行为。【参考方案2】:

我认为主要问题是声明vector&lt;Node&gt; vec(n),它在您另外添加另一个具有单独值的n 节点之前使用n“空”节点初始化向量。因此,如果您按升序排序,然后打印第一个 n 节点,则很可能会打印“空”节点,即具有值 0 的节点(在开始时会发光)。

所以主要你应该写

vector<Node> vec;

此外,正如其他人所说,用于std::sort 的比较函数必须满足 严格的弱排序关系(参见cppreference.com):

应用于对象的函数调用操作的返回值 Compare 类型的,当上下文转换为 bool 时,如果 调用的第一个参数出现在严格的第二个之前 此 Compare 类型引起的弱排序关系,为 false 否则。

这意味着,除其他要求外,...

对于所有 a,comp(a,a)==false

【讨论】:

如果向量中有重复项,程序仍然会出错。需要更改排序比较功能(除了向量push_back 调用的问题)。由于不正确的比较函数,在 Visual C++ 调试模式下运行程序(包括您的更改)在 std::sort 调用上崩溃。 另外,你的答案实际上是一个函数声明,并没有创建vector&lt;Node&gt;

以上是关于使用自定义排序对向量进行排序的主要内容,如果未能解决你的问题,请参考以下文章

类自定义排序的 C++ 向量

使用自定义谓词对 numpy 数组进行排序

使用自定义比较器进行排序时出现运行时错误

使用 Jquery Datatables 对数据排序属性中的值进行自定义排序

自定义对象的排序向量

使用自定义排序顺序对对象的 ArrayList 进行排序