C++ 如何根据另一个向量的排序对向量进行排序?
我有四个向量,我想对它们进行排序C++ 如何根据另一个向量的排序对向量进行排序?,c++,sorting,vector,C++,Sorting,Vector,我有四个向量,我想对它们进行排序 vector<string> color; vector<string> shape; vector<int> size; 所以我要做的是,按颜色对颜色向量进行排序,然后根据重新排列的颜色向量对其他两个向量进行排序。然后在每组颜色(即红色)中,我想按形状排序,并根据排序重新排列大小向量。最后我想对每组颜色和形状中的大小向量进行排序。我想我知道怎么做,但感觉非常混乱,很难概念化/阅读(我对C++还是新手)。有没有一个简单的方法
vector<string> color;
vector<string> shape;
vector<int> size;
所以我要做的是,按颜色对颜色向量进行排序,然后根据重新排列的颜色向量对其他两个向量进行排序。然后在每组颜色(即红色)中,我想按形状排序,并根据排序重新排列大小向量。最后我想对每组颜色和形状中的大小向量进行排序。我想我知道怎么做,但感觉非常混乱,很难概念化/阅读(我对C++还是新手)。有没有一个简单的方法来完成这样的事情
例如,我想做这样的事情:
Blue Circle 1 -> Red Triangle 1
Red Triangle 1 -> Red Triangle 2
Blue Circle 3 -> Red Triangle 3
Red Triangle 3 -> Red Circle 1
Red Circle 2 -> Red Circle 2
Blue Triangle 1 -> Red Circle 3
Red Circle 1 -> Blue Triangle 1
Blue Triangle 3 -> Blue Triangle 2
Red Circle 3 -> Blue Triangle 3
Blue Circle 2 -> Blue Circle 1
Blue Triangle 2 -> Blue Circle 2
Red Triangle 2 -> Blue Circle 3
#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
struct Shape
{
std::string color_;
std::string shape_;
int size_;
Shape(const std::string& color, const std::string& shape, int size)
: color_(color)
, shape_(shape)
, size_(size)
{}
// returns true if this shape is less than the other shape
// "less than" is up to us: here we give priority to color, then shape, then size
bool operator<(const Shape& other) const
{
// std::tie makes lexicographical compare of complex structures easy!
return (std::tie(color_, shape_, size_) <
std::tie(other.color_, other.shape_, other.size_));
}
friend std::ostream& operator<<(std::ostream& os, const std::vector<Shape>& shapes)
{
for (auto& shape : shapes)
{
os << shape.color_ << " " << shape.shape_ << " " << shape.size_ << "\n";
}
return os;
}
};
int main(int argc, char** argv)
{
std::vector<Shape> shapes;
shapes.emplace_back("Blue", "Circle", 1);
shapes.emplace_back("Red", "Triangle", 1);
shapes.emplace_back("Blue", "Circle", 3);
shapes.emplace_back("Red", "Triangle", 3);
shapes.emplace_back("Red", "Circle", 2);
shapes.emplace_back("Blue", "Triangle", 1);
shapes.emplace_back("Red", "Circle", 1);
shapes.emplace_back("Blue", "Triangle", 3);
shapes.emplace_back("Red", "Circle", 3);
shapes.emplace_back("Blue", "Circle", 2);
shapes.emplace_back("Blue", "Triangle", 2);
shapes.emplace_back("Red", "Triangle", 2);
std::cout << "Pre sorted vector:\n";
std::cout << shapes;
// std::sort by default will use the operator< for the types
// being sorted, if it's available
std::sort(shapes.begin(), shapes.end());
std::cout << "\nPost sorted vector:\n";
std::cout << shapes;
}
正如前面指出的,您应该创建一个结构
,然后创建一个std::vector
,然后可以根据颜色进行排序。以下是一个解决方案:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
struct MyStruct
{
std::string color;
std::string shape;
int size;
MyStruct(std::string co, std::string sh, int si):
color{co}, shape{sh}, size{si} {};
};
bool MyComp(MyStruct a,MyStruct b)
{
auto f = [](unsigned char c){ return std::tolower(c);};
std::transform(a.color.begin(), a.color.end(), a.color.begin(),f);
std::transform(b.color.begin(), b.color.end(), b.color.begin(),f);
return (a.color < b.color);
}
int main() {
std::vector<MyStruct> MyVec;
MyVec.emplace_back("Blue","Circle",1);
MyVec.emplace_back("Red","Triangle",1);
MyVec.emplace_back("Blue","Circle",3);
MyVec.emplace_back("Red","Triangle",3);
MyVec.emplace_back("Red","Circle",2);
MyVec.emplace_back("Blue","Triangle",1);
MyVec.emplace_back("Red","Circle",1);
MyVec.emplace_back("Blue","Triangle",3);
MyVec.emplace_back("Red","Circle",3);
MyVec.emplace_back("Blue","Circle",2);
MyVec.emplace_back("Blue","Triangle",2);
MyVec.emplace_back("Red","Triangle",2);
std::sort(MyVec.begin(), MyVec.end(), MyComp);
for(auto s : MyVec)
std::cout << s.color << " " << s.shape << " " << s.size << std::endl;
return 0;
}
您应该创建一个
形状
类或结构,然后创建一个std::vector
,然后可以根据颜色进行排序,主要是根据其他参数进行排序。定义重载的运算符第一个解决方案
解决此问题的一种方法是不对向量进行排序,而是生成一个新的索引向量,我们将其命名为I
,这样排序向量中位于j
位置的项在当前未排序向量中位于I[j]
位置
通过使用递增的值0.初始化该索引向量,可以很容易地生成该索引向量。。n-1
并使用自定义比较函数对向量进行排序:
std::vector<int> I(N);
std::iota(begin(I), end(I), 0);
std::sort(begin(I), end(I), [&](int ia, int ib) { return color[ia] < color[ib]; });
// this is a simplified comparison function to not clutter the code
第二种解决方案
第一种解决方案是可行的,但由于许多原因,它可能不符合您的喜好。也许您不喜欢这样一个事实:当您按升序遍历项目时,它会随机化内存访问(以及相关的惩罚)。或者你真的需要对向量进行排序,因为你必须把它们传递给另一个组件
在这种情况下,您仍然可以使用第一个方法作为第一步,然后根据刚刚计算的索引对向量重新排序。以下是形状
向量的这种重新排序示例:
std::vector<std::string> tmp_shape;
tmp_shape.reserve(N);
for(int j=0; j<N; ++j)
tmp_shape.emplace_back(std::move(shape[I[j]]));
shape.swap(tmp_shape);
std::向量tmp_形;
tmp_形保留区(N);
对于(int j=0;jj),您应该创建一个形状
类或结构,然后创建一个std::vector
,然后可以根据颜色进行排序。谢谢,我会研究它。这是否也可以让我像我的示例中那样进行级联排序?“级联”排序将仅取决于比较器运算符。可以在std::tuple
上观察到所需排序的示例(请参见示例代码):比较器函数有一行代码:返回std::tie(color\uu,shape\uu,size\uu)Pre sorted vector:
Blue Circle 1
Red Triangle 1
Blue Circle 3
Red Triangle 3
Red Circle 2
Blue Triangle 1
Red Circle 1
Blue Triangle 3
Red Circle 3
Blue Circle 2
Blue Triangle 2
Red Triangle 2
Post sorted vector:
Blue Circle 1
Blue Circle 2
Blue Circle 3
Blue Triangle 1
Blue Triangle 2
Blue Triangle 3
Red Circle 1
Red Circle 2
Red Circle 3
Red Triangle 1
Red Triangle 2
Red Triangle 3
std::vector<int> I(N);
std::iota(begin(I), end(I), 0);
std::sort(begin(I), end(I), [&](int ia, int ib) { return color[ia] < color[ib]; });
// this is a simplified comparison function to not clutter the code
auto shape3 = shape[I[3]];
std::vector<std::string> tmp_shape;
tmp_shape.reserve(N);
for(int j=0; j<N; ++j)
tmp_shape.emplace_back(std::move(shape[I[j]]));
shape.swap(tmp_shape);