根据某一行

时间:2017-01-21 11:19:39

标签: c++ sorting vector

我有兴趣在第二行的基础上对整个2d矢量进行排序。我尝试了一些仅排序第二行的代码,但是,我想要它用于整个2d向量。

#include<iostream>
#include<vector> 
#include<algorithm> 
int main()
{
    std::vector< std::vector<int> > vect{{3, 5, 1},
                                         {4, 8, 6},
                                         {7, 2, 9}};
    int m = vect.size();
    int n = vect[0].size();
    sort(vect[1].begin(), vect[1].end());
    std::cout << "After sorting :\n";
    for (int i=0; i<m; i++)
    {
        for (int j=0; j<n ;j++)
            std::cout << vect[i][j] << " ";
        std::cout << std::endl;
    }
    return 0;
}

输出如下:

3 5 1 
4 6 8 
7 2 9 

但我希望它是

3 1 5
4 6 8
7 9 2

4 个答案:

答案 0 :(得分:2)

创建一个转置向量的函数,因此它应该将{{3,5,1},{4,8,6},{7,2,9}}修改为{{3,4,7}, {5,8,2},{1,6,9}}。使用您的函数转置向量,然后使用自定义比较器对向量进行排序,比较行的第二个元素。然后再次调用转置函数。

转置功能可能看起来像

std::vector< std::vector<int> > transpose(std::vector< std::vector<int> >& vect)
{
 std::vector< std::vector<int> > transposed(vect[0].size(), std::vector<int>());
 for (size_t i = 0; i < vect.size(); ++i)
  for (size_t j = 0; j < vect[0].size(); ++j)
    transposed[j].push_back(vect[i][j]);
 return transposed;
}

然后整个代码将是

vect = transpose(vect);                                     
std::sort(vect.begin(), vect.end(), 
  [](const std::vector<int>& lhs, const std::vector<int>& rhs)
     {return lhs[1] < rhs[1];});                                     
vect = transpose(vect);                                     

如果矢量是正方形,则可以在适当的位置进行转置,使得解决方案比这个通用的更有效。

答案 1 :(得分:1)

问题的结构不允许我们使用内置的排序功能。因为,自定义排序只会提供“行”。而且你只能比较“行”。

但是有一些替代方法可以实现这一目标。

例如,你可以通过转置矢量矢量来做到这一点。

“转置&gt;按列排序&gt;转置”可以解决您的问题。

但我的解决方案是基于另一种动态。

  1. 排序第n列并将索引保​​留为数组。 (n是有序行的位置)
  2. 使用步骤1中定义的数组,逐个排序所有行。
  3. http://cpp.sh/4dkzg

    #include<iostream>
    #include<vector> 
    #include<algorithm> 
    
    using namespace std;
    
    template <typename T>
    vector<size_t> sort_indexes(const vector<T> &v) {
    
      // initialize original index locations
      vector<size_t> idx(v.size());
      iota(idx.begin(), idx.end(), 0);
    
      // sort indexes based on comparing values in v
      sort(idx.begin(), idx.end(),
           [&v](size_t i1, size_t i2) {return v[i1] < v[i2];});
    
      return idx;
    }
    
    int main()
    {
        std::vector< std::vector<int> > vect{{3, 5, 1, 2},
                                             {4, 8, 6, 1},
                                             {7, 2, 9, 5}};
        int m = vect.size();
        int n = vect[0].size();
    
        int sortByRow = 1; // starts from 0, if 1 => order by using 2nd row.
    
        /* generate reference for our actual sort operation */
        std::vector<size_t> indexSort = sort_indexes(vect[sortByRow]);
    
        /* sort each row using our reference vector */
        for (int i=0; i<m; i++)
        {      
            int temp[n];
            for (int j=0; j<n; j++)
                temp[j] = vect[i][indexSort[j]];
    
            // Copy back temp[] to vector
            for (int j=0; j<n; j++)
                vect[i][j]  = temp[j];
    
        }
    
        std::cout << "After sorting :\n";
        for (int i=0; i<m; i++)
        {
            for (int j=0; j<n ;j++)
                std::cout << vect[i][j] << " ";
            std::cout << std::endl;
        }
        return 0;
    }
    

    http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/(如果您想应用就地排序,则有一些修复方法)

答案 2 :(得分:0)

你可以std::vector std::pair<int,int> std::vector< std::vector<int> > vect{{ 3, 5, 1 },{ 4, 8, 6 },{ 7, 2, 9 }}; std::vector<std::pair<int, int>> row; for (int i = 0; i < vect[1].size(); ++i){ row.push_back({vect[1][i],i}); } sort(row.begin(), row.end()); std::vector< std::vector<int> > sorted; std::vector<int> sortedRow; for (int i = 0; i < vect.size(); ++i){ for (int j = 0; j < vect[i].size(); ++j){ sortedRow.push_back(vect[i][row[j].second]); } sorted.push_back(sortedRow); sortedRow.clear(); } 在向量的第i个元素的第一个变量中你有第二行的第i个值,而在第二个变量你有索引i的值。

然后根据对的第一个值对该向量进行排序。这样你就可以制作一个新的2D向量,在每一行中你根据对的第二个值(即旧索引)对元素进行排序。

#include <utility>

你必须app:showAsAction="always||collapseActionView"

答案 3 :(得分:0)

这段代码非常脏。但是你想要的代码完全相同。

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

std::vector< std::vector<int> > vect = { {3, 5, 1}, {4, 8, 6}, {7, 2, 9} };

int findInVector(std::vector<int> input, int temp)
{
    for(int i=0;i<input.size();i++)
    {
        if(input[i] == temp)
        {
            return i;
        }
    }
}

bool myfunction (int i,int j)
{

    bool ret;

    if(i<j)
    {
        int i_pos = findInVector( vect[1], i);
        int j_pos = findInVector( vect[1], j);

        int temp  = vect[0][i_pos];
        vect[0][i_pos] = vect[0][j_pos];
        vect[0][j_pos] = temp;

        temp  = vect[2][i_pos];
        vect[2][i_pos] = vect[2][j_pos];
        vect[2][j_pos] = temp;

        ret = true;
    }
    else
    {
        ret = false;
    }

    return ret;
}

int main()
{
    int m = vect.size();
    int n = vect[0].size();
    sort(vect[1].begin(), vect[1].end(), myfunction);
    std::cout << "After sorting :\n";
    for (int i=0; i<m; i++)
    {
        for (int j=0; j<n ;j++)
            std::cout << vect[i][j] << " ";
        std::cout << std::endl;
    }
    return 0;
}