【问题标题】:How do I sort a 2d string array by a specific column's values in C++?如何按 C++ 中特定列的值对二维字符串数组进行排序?
【发布时间】:2021-02-23 23:43:39
【问题描述】:

我有以下从外部 .txt 文件获取/创建的二维数组。

string accountsArr[5][7] = {
  "bham@gnet.com", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
  "jdark@att.net", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
  "hgreen@lakes.net", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
  "tsmith@dna.com", "Tom", "Smith", "tuna20", "2000", "U", "Teacher",
  "jarrow@pnet.com", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice"
};

我需要根据“姓氏”列(每行的列索引 2)对这个数组进行排序,所以我基本上最终得到:

string accountsArr[5][7] = {
  "jarrow@pnet.com", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice",
  "jdark@att.net", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
  "hgreen@lakes.net", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
  "bham@gnet.com", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
  "tsmith@dna.com", "Tom", "Smith", "tuna20", "2000", "U", "Teacher"
};

我将如何以编程方式执行此操作?使用 std::sort 不起作用。我不断收到use of undeclared identifier sort

int n = sizeof(accountsArr[0]) / sizeof(accountsArr[0][0]);
std::sort(accountsArr, accountsArr + n);

更新:我需要/想知道如何在原始字符串数组上执行此操作(没有向量、结构等)。

【问题讨论】:

  • 您是否尝试过使用std::sort?你知道如何在 C++ 中使用它吗?您的 C++ 教科书中是否有 std::sort 的示例可供您查看?有什么关于排序的具体内容您不确定吗?
  • 为什么不为每个字段创建一个struct,然后重载operator <
  • @SamVarshavchik 问题是我的教科书似乎没有进入二维数组。它展示了很多只有数字的一维数组的例子,这比我目前试图解决的问题要简单得多。
  • 对一维数组、二维数组或 42 维数组进行排序没有根本的不同。基本原理都是一样的。不幸的是,我们不会在 stackoverflow.com 上为其他人编写代码。您需要展示您对数组进行排序的尝试,并说明您的具体问题是什么。
  • 我有没有声称你能找到它?我说的恰恰相反:你不太可能找到碰巧写过相同类型的其他人。 C++ 是当今使用的最复杂的通用编程语言。试图通过寻找其他人做同样的事情并在不学习基本原理的情况下复制它来在 C++ 中实现某些东西是行不通的。您需要了解排序的工作原理,在 C++ 中,std::sort 的工作原理,然后弄清楚如何使其工作 与您的数组。 C++ 没有即时满足感。

标签: c++ arrays sorting multidimensional-array bubble-sort


【解决方案1】:

让我给你一个更好的方法来解决你的问题,使用std::sort

首先,为您的数据创建适当的结构。我会稍微简化你的条目。我们也已经为此实现了operator<,因为我们以后需要它。

struct Person
{
    string first_name;
    string last_name;
    string email;

    Person(const string& first_name, const string& last_name, const string& email) :
        first_name(first_name), last_name(last_name), email(email) {}

    bool operator<(const Person& other) const { return last_name < other.last_name; }
};

C++ 是一种面向对象的语言,如果你有任何一种有规律的结构化数据,它至少应该是一种结构。由于我们不需要封装,没有办法使对象无效,我们可以将其保留为结构,否则我们会选择一个类。

原始数组通常不是存储数据的好方法。使用一个的唯一充分理由是当必须对速度进行超优化时。因此,我们现在将您的原始数组转换为适当的容器:

vector<Person> persons;
persons.reserve(rows); // <-- reserve allows for the memory to be properly pre-allocated
for(size_t i=0; i<rows; i++)
{
    persons.push_back(Person(accountsArr[i][1], accountsArr[i][2], accountsArr[i][0]));
}

现在我们在定义operator&lt; 的结构上拥有一个合适的容器,我们剩下要做的就是调用std::sort

std::sort(persons.begin(), persons.end());

完成。

我们还可以考虑创建一个类 Persons 来处理所有这些,并使用一个方法 read_file(const string&amp; file) 读取数据,将其放入成员向量中,然后对其进行排序。

无论如何,对于未来,如果人们告诉你使用std::sort,搜索有关如何使用它的教程不会有什么坏处。它还有一些其他功能可以提供。去寻找它的描述,比如https://en.cppreference.com/w/cpp/algorithm/sort,并确保阅读并理解其中的所有内容。
在这种情况下,您可以编写一个简单的冒泡排序,但是当您编程时,您希望尽可能少地自己做。 STL 函数很可能更有效(您的排序在 O(N²) 中,但排序可以在 O(NlogN) 中完成)并且经过反复测试(创建错误很容易发生)。

此外,STL 有一个built in std::swap,因为您在自定义冒泡排序中自己定义了一个。

无论如何,请考虑将您的一些未来代码放在CodeReview

编辑:当您在问题中写了有关“未识别标识符排序”的内容时,如果您需要功能,则需要包含标题。在std::sort的情况下,正确的包含是#include &lt;algorithm&gt;

【讨论】:

    【解决方案2】:

    所以我最终通过“冒泡排序”解决了这个问题。这是我实现它的方式。希望这可以帮助其他无法找到按特定列对二维数组进行排序的示例的人:

    int rows = 5;
    int col = 7;
    string accountsArr[rows][col] = {
      "bham@gnet.com", "Blake", "Ham", "squid62", "1987", "U", "Teacher",
      "jdark@att.net", "Jim", "Dark", "gymrat32", "1985", "A", "Master",
      "hgreen@lakes.net", "Hannah", "Green", "flower22", "2007", "U", "Apprentice",
      "tsmith@dna.com", "Tom", "Smith", "tuna20", "2000", "U", "Teacher",
      "jarrow@pnet.com", "James", "Arrow", "ahoy10", "2005", "U", "Apprentice"
    };
    
    //do a bubble sort
    for(int maxElement = rows - 1; maxElement > 0; maxElement--){
      for(int i = 0; i < maxElement; i++){
        //if current row "last name" column is > the next row "last name" column, swap them
        if(theAccounts[i][2] > theAccounts[i + 1][2]){
          std::swap(theAccounts[i], theAccounts[i + 1]);
        }
      }
    }
    

    【讨论】:

    • 它在技术上是可行的,但是你使用的是具有 O(N²) 复杂度的简单冒泡排序。对于一小组数据来说不是那么问题。但无论如何,完全没有必要。 std::sort 是一个东西。
    • 如果在文档或我的教科书中更清楚地表明 std::sort 函数需要大量额外的工作才能使排序正常工作,那就太好了。我专门使用原始字符串数组,并且需要能够按原样对其进行排序。
    • 你所谓的额外工作是无论如何你都应该做的,即使你不会使用std::sort。好的代码的一个关键特征是可读性。你会记得一年后连续第三个条目是姓氏吗?特别是当数组不是硬编码而是从文件中读取时?另外,你总是正好有五行吗?如果它可以是动态的,你真的想要动态内存分配的麻烦吗(要求你稍后delete)?当你编写大算法并将特定算法放在一个函数中时,你真的希望数组衰减为指针作为参数吗?
    猜你喜欢
    • 2012-11-15
    • 2015-10-13
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2021-08-16
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多