【问题标题】:How to sort an array of struct/class based on its member data?如何根据其成员数据对结构/类数组进行排序?
【发布时间】:2020-04-24 17:34:03
【问题描述】:

如果失败,如何根据其成员数据对结构/类数组进行排序?

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;                                          

struct O{
    const string n;
    int a=1;
};

bool bfunction (O a, O b) {
    return a.n < b.n; }

int main () {

    O m[]={ {"unta"}, {"jalan"}, {"sama"}, {"aki"} };


// using function in sort control
    sort (m.begin(), m.end(), &bfunction);
}

gcc 给出:

 error: request for member ‘begin’ in ‘m’, which is of non-class type ‘O [4]’
     sort (m.begin(), m.end(), &bfunction);
             ^~~~~
 error: request for member ‘end’ in ‘m’, which is of non-class type ‘O [4]’
     sort (m.begin(), m.end(), &bfunction);
                        ^~~~~

感谢真诚有用的帮助

【问题讨论】:

  • 这能回答你的问题吗? How can I sort the array of class?
  • 您的实际问题是,m 是一个 O[],它没有任何功能。使用std::vector。 (您尝试在O[] 上调用.begin())并在您的排序函数中比较字符串数组。你想比较两个字符串吗?
  • C 样式数组没有 begin()end() 成员。请改用std::begin()std::end()(或std::array)。
  • @churill 或使用std::begin()std::end(),它们适用于固定数组。但是代码仍然会失败,因为a.n &lt; b.n 没有为string[] 数组定义。而且,bfunction() 需要通过引用来获取它的参数

标签: c++ arrays algorithm class sorting


【解决方案1】:

使用std::array

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>    

struct O {
    std::string n;
    int a;

    O(const char* c) : a(1) { n = c; }
};

bool bfunction(O a, O b) {
    return a.n < b.n;
}

int main() {
    std::array<O, 4> m = { "unta", "jalan", "sama", "aki" };

    // using function in sort control
    std::sort(m.begin(), m.end(), &bfunction);
}

【讨论】:

  • 我不认为这会解决实际的排序部分,还是会?
  • 它将解决编译问题,这是朝着正确方向迈出的一步
  • 是的,std::array 需要两个模板参数,第二个是大小。
  • 很公平,我打开了 VS2019 并验证了代码现在可以正确构建。编辑了我的答案。谢谢大家!
【解决方案2】:

这里犯了一些错误:

  1. sort (m.begin(), m.end(), &amp;bfunction);O[] 上调用begin()end()。但是数组没有任何成员函数。

    您在这里有一些选择:要么将 m 设为 std::array&lt;O, 4&gt;std::vector&lt;O&gt;,要么使用适用于静态数组的 std::begin(m)std::end(m)

  2. 排序函数应该通过 const 引用获取它的参数:

    bool bfunction (const O &amp;a, const O &amp;b)

  3. 在排序函数a.n &lt; b.n 中比较两个字符串数组,但是这样的比较在任何地方都没有定义。这是一个需要解决的逻辑错误。想想你真正想在这里比较什么。比较是为std::string 定义的,例如return a.n[0] &lt; b.n[0]; 会起作用。

  4. 当对任何元素进行排序时,需要四处移动。但是您的结构 O 没有移动构造函数,因为您没有提供一个,并且自动生成的结构会不正确,因为 Oconst 成员。

    我认为解决这个问题的最佳方法是使所有成员变量私有并通过 getter 和 setter 控制对它们的访问。目前,最简单的方法是删除const

【讨论】:

    【解决方案3】:

    这是一个复制粘贴就绪的示例,说明我将如何做到这一点(假设您的 n 应该只是一个字符串,而不是一个由七个字符串组成的数组)。如果你真的想要一个字符串数组作为n,那么你必须为它们定义一个正确的顺序。

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <array>
    
    class O {
        std::string n;
        int a;
    
    public: 
    
        O(const char* c, int a = 1) : n(c), a(a) {}
    
        const std::string& get_n() const { return n; }
    
    };
    
    bool bfunction(const O& a, const O& b) {
        return a.get_n() < b.get_n();
    }
    
    int main() {
    
        std::array<O, 4> m = { "unta", "jalan", "sama", "aki" };
    
        std::sort(m.begin(), m.end(), &bfunction);
    
        for(auto& x : m) { 
            std::cout << x.get_n() << ',';
        }
    }
    

    直播代码here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2020-06-17
      相关资源
      最近更新 更多