根据一个向量对多个向量进行排序

时间:2017-05-04 16:35:25

标签: c++ sorting vector

我有四个向量,包含圆心的x,y,半径和重量信息。我想按重量顺序(从最高到最低)对它们进行排序,但我真的不知道如何或从哪里开始。我可以将所有向量放在Eigen::Tensor中,以便将数据收集在一个4d矩阵中,如果这有用的话。但除此之外,我不知道。

每个向量包含134个元素,但由于它们中只有一个必须进行排序,这意味着排序算法并不重要。

有没有人提示从哪里开始?

3 个答案:

答案 0 :(得分:0)

首先重构代码并将四个向量转换为一个结构向量可能更有意义。 这样的事情:

struct CircleInfo
{
    int x, y, radius, weight;
};

std::vector<CircleInfo> circles;

然后,如果你想要sort by radius

#include <vector>
#include <algorithm>
#include <iostream>

struct CircleInfo
{
    int x, y, radius, weight;
};

int main()
{
    std::vector<CircleInfo> circles;
    CircleInfo ci1 = { 1,1,1,1 };
    CircleInfo ci2 = { 3,3,3,3 };
    circles.push_back(ci2);
    circles.push_back(ci1);
    std::cout << "before sort circles[0].radius: " << circles[0].radius << std::endl;
    std::sort(circles.begin(), circles.end(), [](const CircleInfo& c1, const CircleInfo& c2) {
        return c1.radius < c2.radius;
    });
    std::cout << "aftern sort circles[0].radius: " << circles[0].radius << std::endl;
}

输出:

before sort circles[0].radius: 3
after sort circles[0].radius: 1

此代码使用std::sort和自定义函数来比较两个圆圈。要按半径进行比较,您需要更新它以将c1.weightc2.weight进行比较。

答案 1 :(得分:0)

使用ranges-v3,您可以执行类似

的操作
ranges::sort(ranges::view::zip(xs, ys, radiuses, weights),
             std::greater<>{}, // decreasing order
             [](const auto& t){ return std::get<3>(t); }); // Projection: use weight

Demo

但是让课程Circle有意义,这样可以避免压缩数组,并允许更短的投影。

答案 2 :(得分:0)

您可以创建第5个索引向量,根据4个向量之一对索引向量进行排序,然后在O(n)时间内重新排序所有4个向量(并对索引向量进行排序)。根据其中一个向量(年龄向量)对3个向量进行排序的示例。创建索引I的向量然后根据A(使用lambda compare)进行排序,然后根据I重新排序所有3个向量和I,通过撤消&#34;循环&#34;在我。

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

int main()
{
    std::vector <int> A;                // ages
    std::vector <std::string> N;        // names
    std::vector <int> Z;                // zip codes
    std::vector <size_t> I;             // indices
    int tA;
    std::string tN;
    int tZ;

    A.push_back(37);
    N.push_back("Ted");
    Z.push_back(54211);
    A.push_back(21);
    N.push_back("John");
    Z.push_back(53421);
    A.push_back(31);
    N.push_back("Fred");
    Z.push_back(52422);
    A.push_back(21);
    N.push_back("Sam");
    Z.push_back(51422);
    // display the vectors
    for(size_t i = 0; i < A.size(); i++)
        std::cout << std::setw(6) << N[i]
            << std::setw(8) << Z[i]
            << std::setw(4) << A[i] << std::endl;
    std::cout << std::endl;
    // initialize the vector of indices
    for(size_t i = 0; i < A.size(); i++)
        I.push_back(i);
    // sort I according to A
    std::stable_sort(I.begin(), I.end(),
        [&A](size_t i, size_t j) {return 
        A[i] < A[j];});
    // reorder A, N, Z in place also restore I
    // time complexity is O(n)
    for(size_t i = 0; i < A.size(); i++){
        size_t j, k;
        if(i != I[i]){
            tA = A[i];
            tN = N[i];
            tZ = Z[i];
            k = i;
            while(i != (j = I[k])){
                A[k] = A[j];
                N[k] = N[j];
                Z[k] = Z[j];
                I[k] = k;
                k = j;
            }
            A[k] = tA;
            N[k] = tN;
            Z[k] = tZ;
            I[k] = k;
        }
    }
    // display the sorted vectors
    for(size_t i = 0; i < A.size(); i++)
        std::cout << std::setw(6) << N[i]
            << std::setw(8) << Z[i]
            << std::setw(4) << A[i] << std::endl;
    return 0;
}