给定一个类型的行主表std::vector<std::vector<T>>(其中T是不太可比的类型,如intor std::string),我想按特定列对表进行排序,同时保留行内容(即一行只能作为一个整体移动,而不是单个细胞)。
例如,给定此表:
2 8 1 4
3 7 6 7
3 3 4 9
8 6 3 4
7 1 5 7
Run Code Online (Sandbox Code Playgroud)
按第三列(索引 2)排序,所需的结果将是:
2 8 1 4
8 6 3 4
3 3 4 9
7 1 5 7
3 7 6 7
Run Code Online (Sandbox Code Playgroud)
STL 实现这一目标的方法是什么?
我能想到的一种解决方案是将应排序的列复制到关联容器中(例如,std::unordered_map<T, std::size_t>键是单元格值,值是行索引),然后按键对映射进行排序(使用std::sort()),提取结果行索引顺序并使用它对原始表中的行重新排序。
然而,当将其编写为实际代码时,该解决方案似乎不优雅且相当冗长。
有哪些可能的、“好的”解决方案来实现这一点?
注意:表类型std::vector<std::vector<T>>是给定的,不能更改/修改。
使用比较器来比较要比较的元素。
std::vector<std::vector<T>> vec;
// add elements to vec
int idx = 2;
std::sort(vec.begin(), vec.end(), [idx](const std::vector<T>& a, const std::vector<T>& b) {
return a.at(idx) < b.at(idx);
});
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <vector>
#include <algorithm>
typedef int T;
int main() {
std::vector<std::vector<T>> vec = {
{2, 8, 1, 4},
{3, 7, 6, 7},
{3, 3, 4, 9},
{8, 6, 3, 4},
{7, 1, 5, 7}
};
int idx = 2;
std::sort(vec.begin(), vec.end(), [idx](const std::vector<T>& a, const std::vector<T>& b) {
return a.at(idx) < b.at(idx);
});
for (size_t i = 0; i < vec.size(); i++) {
for (size_t j = 0; j < vec[i].size(); j++) {
std::cout << vec[i][j] << (j + 1 < vec[i].size() ? ' ' : '\n');
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过使用 的自定义投影函数来完成此操作std::ranges::sort。
#include <algorithm>
#include <vector>
int main() {
std::vector<std::vector<int>> v{
{2, 8, 1, 4},
{3, 7, 6, 7},
{3, 3, 4, 9},
{8, 6, 3, 4},
{7, 1, 5, 7}
};
int col = 2;
std::ranges::sort(
v, {}, [&col](auto& x) { return x[col]; }
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
678 次 |
| 最近记录: |