将二维字符串数组与std::sort进行比较
compare 2 dimensional string array with std::sort
我有一个字符串数组,里面有我想排序的数字(我只想对[I][0]进行排序):
string test[4][2];
test[0][0] = "3";
test[0][1] = "4";
test[1][0] = "1";
test[1][1] = "2";
test[2][0] = "6";
test[2][1] = "8";
test[3][0] = "5";
test[3][1] = "4";
std::sort(std::begin(test), std::end(test), NumericGreaterThan);
bool NumericGreaterThan(const string u[], const string v[])
{
// more code ..
return true;
}
结果应该是:
1 - 2
3 - 4
5 - 4
6 - 8
编译器说:[Error] invalid array assignment
更新
上面的例子只是一个测试用例。事实上,我的第2个数组维度比示例中的要宽。例如:
string test[4][2];
test[0][0] = "3";
test[0][1] = "Name";
test[0][2] = "Name";
test[0][3] = "5";
基于@coincoin的解决方案,我做了这样的事情:
// create tmp array with index and sorting value
int testsCount = sizeof(test) / sizeof(test[0]);
vector< pair<string, string> > tmpTest;
for (int i = 0; i < testsCount; i++) {
pair<string, string> aPair;
aPair.first = std::to_string(i);
aPair.second = test[i][3];
tmpTest.push_back(aPair);
}
// sort
std::sort(std::begin(tmpTest), std::end(tmpTest), compare);
bool compare(const pair<string, string>&i, const pair<string, string>&j)
{
return std::stoi(i.second)>std::stoi(j.second);
}
现在我有一个test
的复制和排序向量,我可以使用它来循环遍历原始测试数组。
for (int i = 0; i < testsCount; i++) {
cout << i+1 << ". " << test[std::stoi(tmpTest[i].first)][0] << endl;
}
我知道这不是实现这一目标的最佳方式,但它符合我的需求。
我认为你不必要地把事情过于复杂了(还有一些答案…)
您应该修改您的代码设计。
例如,你可以简单地使用一个成对的数组,你可以重用内置的bool operator< (const pair<T1,T2>& lhs, const pair<T1,T2>& rhs)
,它可以做你想做的事情。。。
#include <array>
#include <algorithm>
int main() {
std::array<std::pair<int,int>, 4> test { std::make_pair(3,4), std::make_pair(1,2), std::make_pair(6,8), std::make_pair(5,4) };
std::sort(std::begin(test), std::end(test));
}
实时代码
输出为
(1,2)(3,4)(5,4)(6,8)
仅此而已。。。
为了对数组进行排序,必须将一个数组分配给另一个数组,这是不可能的。您可能应该使用一个成对的数组并比较成对。
您可以将字符串的每一部分分为不同的类,然后只寻址排序函数中最低的子类。这有点复杂,但回答了你的问题。
请注意:此方法只允许迭代最低的子类。我不建议在实际使用中使用此方法,因为它不可扩展,并且随着应用程序的维度结构的增加,它会变得越来越复杂。对于每个新的维度,你都需要一个新的类(随着你的"数组变得越来越n维",这变得越来越乏味)。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class string_container_length {
public:
string_container_length(int &length)
{
level2.resize(length);
}
// Level to iterated [i][0] where i is important.
std::vector<std::string> level2;
};
class string_container {
public:
string_container(int &length, int &width)
{
level1.reserve(width);
for (int i = 0; i < width; ++i)
{
// Creates a new string_container_length using constructor with a set length.
level1.push_back(string_container_length(length));
}
}
std::vector<string_container_length> level1;
};
int main(){
// Will not be iterated in example.
int length = 2;
// Will be iterated in example
int width = 4;
string_container test(length,width);
test.level1[0].level2[0] = 7;
test.level1[0].level2[1] = 4;
test.level1[0].level2[2] = 3;
test.level1[0].level2[3] = 8;
// Passes beginning and end positions to the child class.
std::sort(std::begin(test.level1[0].level2), std::end(test.level1[0].level2));
}
推荐:在另一个命名空间下专门为您的需要编写自己的自定义排序函数。这可以使用一个简单的循环、几个if语句和您已经存在的NumericGreaterThan()
函数来完成。关于排序函数如何工作的示例和教程可以在这里找到。
首选std::array<>
而非C阵列:
auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
{"1"s, "2"s},
{"6"s, "8"s},
{"5"s, "4"s}};
std::sort(std::begin(test), std::end(test), NumericGreaterThan);
auto NumericGreaterThan(const std::array<std::string, 2>& u, const std::array<std::string, 2>& v)
-> bool
{
// more code ..
return true;
}
这是未经测试的代码!
在介绍C++习语之前,许多教科书都会先教你C风格。我认为,那些人做得不对。
如果这是唯一一个使用NumericGreaterThan:的地方,也可以考虑使用Lambdas
auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
{"1"s, "2"s},
{"6"s, "8"s},
{"5"s, "4"s}};
std::sort(std::begin(test), std::end(test),
[](const std::array<std::string, 2>& u, const std::array<std::string, 2>& v)
-> bool {
// more code ..
return true;
});
如果您已经使用了C++14,那么您可以使用通用Lambda,这会使代码变得更简单一点:
auto test = std::array<std::array<std::string, 2>, 4>{{"3"s, "4"s},
{"1"s, "2"s},
{"6"s, "8"s},
{"5"s, "4"s}};
std::sort(std::begin(test), std::end(test),
[](const auto& u, const auto& v) -> bool {
// more code ..
return true;
});
还请考虑在排序之前将字符串数组转换为数字。这显著减少了array<string>
->int
转换的次数:
int convertToNumber(std::array<std::string, 2>);
auto test =
std::array<std::pair<std::array<std::string, 2>, int> 4>{{{"3"s, "4"s}, 0},
{{"1"s, "2"s}, 0},
{{"6"s, "8"s}, 0},
{{"5"s, "4"s}, 0}};
for(auto& i: test) i.second = convertToNumber(i.first);
std::sort(std::begin(test), std::end(test),
[](const auto& u, const auto& v) -> bool {
return u.second > v.second;
});
- std::sort()函数无法对向量的一部分进行排序
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- C++中"std::sort"比较器的不同类型
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 使用 std::sort 对向量进行稳定排序
- std::sort 如何处理重复的数字?
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 使用 std::sort 对二维 c 数组进行排序
- std::stable_sort vs std::sort
- 使用 std::sort 对 C 样式的 2D 数组进行部分排序
- std::vector 未按 std::sort 的预期排序
- 隐式转换为比较函数对象(函子)用于 std::sort 而不是 std::map?
- 为什么只有当我的容器有超过 32 个元素时才由 std::sort 调用交换?
- 在 c++ 中使用 std::sort 与迭代器和模板
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果
- 相同的结果 qsort vs std::sort
- 通过 std::sort 对 C 2D 数组进行排序
- 对整个范围进行排序时,std::p artial_sort() 与 std::sort() 的性能?
- 在使用 std::sort() 和 lambda 函数按属性对 ADT 的向量进行排序时遇到问题
- 使用 std::sort 对矩阵进行排序