如何在 C++ 中按特定列的值对二维字符串数组进行排序?

How do I sort a 2d string array by a specific column's values in C++?

我从外部 .txt 文件 get/create 得到以下二维数组。

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);

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

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

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]);
    }
  }
}

让我给你一个更好的方法来解决你的问题,使用 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++ 是一种 object-oriented 语言,如果您有任何类型的规则结构化数据,它至少应该是一种结构。由于我们不需要封装,也没有办法使 object 无效,我们可以将其保留为结构,否则我们会选择 class.

原始数组通常不是存储数据的好方法。使用一个的唯一好理由是当速度必须 hyper-optimized 时。因此,我们现在将您的原始数组转换为合适的容器:

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< 的结构上有了一个合适的容器,我们剩下要做的就是调用 std::sort:

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

完成。

我们还可以考虑创建一个 class Persons 来处理所有这些,有一个方法 read_file(const string& file) 读取数据,将其放入成员向量然后排序它。

无论如何,为了将来,如果有人告诉您使用 std::sort,搜索有关如何使用它的教程也无妨。它还有一些其他功能可以提供。寻找它的描述,例如 https://en.cppreference.com/w/cpp/algorithm/sort,并确保阅读并理解其中的所有内容。
在这种情况下,您可以编写一个朴素的冒泡排序,但在编程时,您希望自己做的事情越少越好。 STL 函数很可能更有效(您的排序在 O(N²) 中,但排序可以在 O(NlogN) 中完成)并且一遍又一遍地测试(很容易产生错误)。

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

无论如何,考虑把你未来的一些代码放在 CodeReview

编辑:当您在问题中写了一些关于“身份不明的标识符排序”的内容时,如果您需要功能,则需要包含 headers。在 std::sort 的情况下,正确的包含是 #include <algorithm>.