【问题标题】:sorting a 2d array by one row按一行对二维数组进行排序
【发布时间】:2018-06-02 02:37:14
【问题描述】:

我有一个非常明确的问题要处理。我需要对数组 [4] [x] 进行降序排序。 从实例中,如果我得到如下值:

{121,120,203,240}
{0.5,0.2,3.2,1.4}
{1.3,1.5,1.2,1.8}
{3  ,2  ,5  ,4  }

所有值都必须按第 4 行排序。因此,我需要这样的输出:

{203,240,121,120}
{3.2,1.4,0.5,0.2}
{1.2,1.8,1.3,1.5}
{5  ,4  ,3  ,2  }

我试过用冒泡排序的方法来做,但它不能正常工作。

【问题讨论】:

  • 冒泡排序怎么不能正常工作?您观察到什么行为,这与预期有何不同?请展示你做了什么。理想情况下,提供minimal reproducible example
  • @Mateusz Staniaszek 这个 {2 ,3 ,4 ,5 } 是升序排列,不是吗?
  • 哦,我的错,我必须在上面更正它。我想过下降。
  • "我试过用冒泡排序法" --> 发表你的尝试。
  • 欢迎来到 StackOverflow。请参阅help centerHow to Ask

标签: c++ arrays algorithm sorting bubble-sort


【解决方案1】:

使用冒泡排序对数组进行排序的简单方法如下所示

#include <iostream>
#include <iomanip>
#include <utility>

int main()
{
    const size_t N = 4;

    double a[][N] =
    {
        { 121, 120, 203, 240 },
        { 0.5, 0.2, 3.2, 1.4 },
        { 1.3, 1.5, 1.2, 1.8 },
        { 3, 2, 5, 4 }
    };

    for (const auto &row : a)
    {
        for (double x : row) std::cout << std::setw( 3 ) << x << ' ';
        std::cout << '\n';
    }
    std::cout << std::endl;

    //  The bubble sort
    for (size_t n = N, last = N; not (n < 2); n = last)
    {
        for (size_t i = last = 1; i < n; i++)
        {
            if (a[N - 1][i - 1] < a[N - 1][i])
            {
                for (size_t j = 0; j < N; j++)
                {
                    std::swap(a[j][i - 1], a[j][i]);
                }
                last = i;
            }
        }
    }

    for (const auto &row : a)
    {
        for (double x : row) std::cout << std::setw( 3 ) << x << ' ';
        std::cout << '\n';
    }
    std::cout << std::endl;

    return 0;
}

程序输出是

121 120 203 240
0.5 0.2 3.2 1.4
1.3 1.5 1.2 1.8
  3   2   5   4

203 240 121 120
3.2 1.4 0.5 0.2
1.2 1.8 1.3 1.5
  5   4   3   2

您只需从 main 中提取冒泡排序的代码,并将其重写为任何二维数组和用作排序标准的任何行的单独函数。

【讨论】:

  • 这不是很有效。我会引入一个对数组(第 4 行值,索引),对其进行快速排序,然后根据排序对的索引重新排列数组。
  • @Michael 创建任意大小的数组已经是低效的了。
【解决方案2】:

如果我们有一个包含并行值的结构而不是并行向量,那么这个问题将很容易解决。

回到这样的结构很容易:只需创建一些包含排序键和索引的中间向量并对其进行排序。

对索引进行排序后,我们可以直接以正确的顺序重新排序所有单个向量。

我会做类似下面的事情(我把它放在一个 Boost 单元测试中,但所做的应该是显而易见的)。

#define BOOST_AUTO_TEST_MAIN
#define BOOST_TEST_MODULE TestPenta
#include <boost/test/auto_unit_test.hpp>

#include <iostream>
#include <vector>

std::vector<int> v1 = {121,120,203,240};
std::vector<float> v2 = {0.5,0.2,3.2,1.4};
std::vector<float> v3 = {1.3,1.5,1.2,1.8};
std::vector<int> v4 = {3  ,2  ,5  ,4  };

std::vector<int> expected_v1 = {203,240,121,120};
std::vector<float> expected_v2 = {3.2,1.4,0.5,0.2};
std::vector<float> expected_v3 = {1.2,1.8,1.3,1.5};
std::vector<int> expected_v4 = {5  ,4  ,3  ,2  };

BOOST_AUTO_TEST_CASE(TestFailing)
{
    // First create an index to sort containing sort key and initial position
    std::vector<std::pair<int,int>> vindex{};
    int i = 0;
    for (auto x: v4){
        vindex.push_back(std::pair<int,int>(x,i));
        ++i;
    }

    // Sort the index vector by key value
    struct CmpIndex {
        bool operator() (std::pair<int, int> & a, std::pair<int, int> & b) { 
            return a.first > b.first ;
        }
    } cmp;

    std::sort(vindex.begin(), vindex.end(), cmp);

    // Now reorder all the parallel vectors using index
    // (of course in actual code we would write some loop if several vector are of the same type).
   // I'm using parallel loops to avoid using too much memory for intermediate vectors

    {
        std::vector<int> r1;
        for (auto & p: vindex){
            r1.push_back(v1[p.second]);
        }
        v1 = r1;
    }
    {
        std::vector<float> r2;
        for (auto & p: vindex){
            r2.push_back(v2[p.second]);
        }
        v2 = r2;
    }
    {
        std::vector<float> r3;
        for (auto & p: vindex){
            r3.push_back(v3[p.second]);
        }
        v3 = r3;
    }
    {
        std::vector<int> r4;
        for (auto & p: vindex){
            r4.push_back(v4[p.second]);
        }
        v4 = r4;
    }

    // Et voila! The vectors are all sorted as expected
    i = 0;
    for (int i = 0 ; i < 4 ; ++i){
        BOOST_CHECK_EQUAL(expected_v1[i], v1[i]);
        BOOST_CHECK_EQUAL(expected_v2[i], v2[i]);
        BOOST_CHECK_EQUAL(expected_v3[i], v3[i]);
        BOOST_CHECK_EQUAL(expected_v4[i], v4[i]);
        ++i;
    }
}

【讨论】:

    猜你喜欢
    • 2013-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2015-09-17
    相关资源
    最近更新 更多