• 对二维数组排序 使得每行每列非递减


    一:题目

    int   a[10][10]={...};  
    要求对a进行排序,使之:  
    1   每行从左到右为非减序列;  
    2   每列从上到下为非减序列;



    二:我的思路

      我的思路就是按照如下方式填数字,从左上角一直到右下角,按照四十五度的斜线一条条地填数字,这样保证下一层斜线里面的数字比上一层大。因为对于“小”来说,它右边的不比它小,它下面的也不比它小,其他的道理一样的,但是对于两个“大”来说,它们的顺序任意,它们只要比“小”大就可以了。

    再给它指定一个方向就行了,先向右上,没法右上就再向左下,这样依次来,如图:




    三:我的代码

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <iomanip>
      4 
      5 using std::cout;
      6 using std::cin;
      7 using std::endl;
      8 
      9 class ArrSort
     10 {
     11 public:
     12     explicit ArrSort(void);
     13     void sort(void);
     14     void showArr(void);
     15 
     16 private:
     17     enum {N = 10};
     18     int m_arr[N][N];
     19 };
     20 
     21 ArrSort::ArrSort(void)
     22 {
     23     for (int i = 0; i < N; i++)
     24     {
     25         for (int j = 0; j < N; j++)
     26         {
     27             m_arr[i][j] = rand() % 100;
     28         }
     29     }
     30 }
     31 
     32 void ArrSort::showArr(void)
     33 {
     34     for (int i = 0; i < N; i++)
     35     {
     36         for (int j = 0; j < N; j++)
     37         {
     38             cout<<std::left<<std::setw(4)<<m_arr[i][j];
     39         }
     40         cout<<endl;
     41     }
     42     cout<<endl;
     43 }
     44 
     45 int cmp(const void* a, const void* b) 
     46 {
     47     return *(int*)a - *(int*)b;
     48 }
     49 
     50 void ArrSort::sort(void)
     51 {
     52     //分配一维数组装原始二维数组中数
     53     int* arrData = new int[N * N];
     54 
     55     //填充一维数组
     56     int pIndex = 0;
     57     while (pIndex < N * N)
     58     {
     59         arrData[pIndex] = m_arr[pIndex / N][pIndex % N];
     60         pIndex++;
     61     }
     62 
     63     //给一维数组排序
     64     qsort(arrData, N*N, sizeof(int), cmp);
     65 
     66     //下面将排好序的一维数组中的数值填到二维数组
     67     struct Postion        //这个结构体是一个坐标,表明二维数组的下标
     68     {
     69         int x;
     70         int y;
     71     };
     72     enum Direction {TopRight, DownLeft};        //枚举表明方向
     73 
     74     pIndex = 0;
     75     Postion pos = {0, 0};
     76     Direction drct = TopRight;        //从向右上角方向开始
     77 
     78     while(true)
     79     {
     80         m_arr[pos.x][pos.y] = arrData[pIndex];
     81 
     82         pIndex++;
     83         if(pIndex == N * N)
     84             break;
     85 
     86         //下面给指向二维数组的坐标增加
     87         if (drct == TopRight)        //判断当前的方向
     88         {
     89             if(pos.y + 1 < N && pos.x -1 >=0)        //还可以向右上
     90             {
     91                 pos.y++;
     92                 pos.x--;
     93             }
     94             else        //不再可以左上就改变方向向左下吧,有三种情况,但分析了三种情况后你会发现只要if else就好了
     95             {
     96                 if (pos.y + 1 < N)
     97                     pos.y++;
     98                 else
     99                     pos.x++;
    100 
    101                 drct = DownLeft;        //设置方向
    102             }
    103         } 
    104         else        //向左下
    105         {
    106             if (pos.y - 1 >= 0 && pos.x + 1 < N)        //还可以向左下
    107             {
    108                 pos.y--;
    109                 pos.x++;
    110             }
    111             else        //不能在向左下了,这时候因为上面是两个条件,共四种组合,所以剩下三种可能
    112             {
    113                 if(pos.x + 1 >= N)
    114                     pos.y++;
    115                 else
    116                     pos.x++;
    117 
    118                 drct = TopRight;
    119             }
    120         }
    121     }
    122 
    123     delete [] arrData;
    124 }
    125 
    126 int main(void)
    127 {
    128     ArrSort my;
    129     my.showArr();
    130     my.sort();
    131     my.showArr();
    132     cin.get();
    133 }
    View Code

    代码中最重要的就是那个给二维数组按照顺序填数了,这里要注意当向左下不能再走时的掉头,有几种可能:

    根据行列的奇数和偶数会有所不同,但是最多就那么三种向右上不能走下去的可能,向左下同理。这是对于情况1,2,3,其实只要一个if else就可以判断了,因为:

    1:y++
    2:x++
    3:x++

    虽然三种情况,但是也就两种判断。运行:




     四:更简单的方法

      其实对于这一题不必那么复杂的,其实只要把那些数字从左到右,从上到下排个序就可以了……这样不就符合题意了吗?如下:

    #include <iostream>
    #include <cstdlib>
    #include <iomanip>
    
    using std::cout;
    using std::cin;
    using std::endl;
    
    class ArrSort
    {
    public:
        explicit ArrSort(void);
        void sort(void);
        void showArr(void);
    
    private:
        enum {N = 10};
        int m_arr[N][N];
    };
    
    ArrSort::ArrSort(void)
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                m_arr[i][j] = rand() % 100;
            }
        }
    }
    
    void ArrSort::showArr(void)
    {
        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < N; j++)
            {
                cout<<std::left<<std::setw(4)<<m_arr[i][j];
            }
            cout<<endl;
        }
        cout<<endl;
    }
    
    int cmp(const void* a, const void* b) 
    {
        return *(int*)a - *(int*)b;
    }
    
    void ArrSort::sort(void)
    {/*
        //分配一维数组装原始二维数组中数
        int* arrData = new int[N * N];
    
        //填充一维数组
        int pIndex = 0;
        while (pIndex < N * N)
        {
            arrData[pIndex] = m_arr[pIndex / N][pIndex % N];
            pIndex++;
        }
    
        //给一维数组排序
        qsort(arrData, N*N, sizeof(int), cmp);
    
        //下面将排好序的一维数组中的数值填到二维数组
        struct Postion        //这个结构体是一个坐标,表明二维数组的下标
        {
            int x;
            int y;
        };
        enum Direction {TopRight, DownLeft};        //枚举表明方向
    
        pIndex = 0;
        Postion pos = {0, 0};
        Direction drct = TopRight;        //从向右上角方向开始
    
        while(true)
        {
            m_arr[pos.x][pos.y] = arrData[pIndex];
    
            pIndex++;
            if(pIndex == N * N)
                break;
    
            //下面给指向二维数组的坐标增加
            if (drct == TopRight)        //判断当前的方向
            {
                if(pos.y + 1 < N && pos.x -1 >=0)        //还可以向右上
                {
                    pos.y++;
                    pos.x--;
                }
                else        //不再可以左上就改变方向向左下吧,有三种情况,但分析了三种情况后你会发现只要if else就好了
                {
                    if (pos.y + 1 < N)
                        pos.y++;
                    else
                        pos.x++;
    
                    drct = DownLeft;        //设置方向
                }
            } 
            else        //向左下
            {
                if (pos.y - 1 >= 0 && pos.x + 1 < N)        //还可以向左下
                {
                    pos.y--;
                    pos.x++;
                }
                else        //不能在向左下了,这时候因为上面是两个条件,共四种组合,所以剩下三种可能
                {
                    if(pos.x + 1 >= N)
                        pos.y++;
                    else
                        pos.x++;
    
                    drct = TopRight;
                }
            }
        }
    
        delete [] arrData;*/
        qsort(m_arr, N*N, sizeof(int), cmp);
    }
    
    int main(void)
    {
        ArrSort my;
        my.showArr();
        my.sort();
        my.showArr();
        cin.get();
    }
    View Code



    五:总结
    (1)C++输出对齐的数字:cout<<std::left<<std::setw(4)<<m_arr[i][j];

    (2)我想的那种奇怪的填充数字的方式

    (3)不要没想清楚、没看看还有没有更简单的方法就开始写代码。

  • 相关阅读:
    Lc40_组合总和II
    Spring整合ZooKeeper基础使用介绍
    常见Bean拷贝框架下划线驼峰互转扩展支持
    ElastchSearch 基本使用姿势
    Java中两种分页遍历的使用姿势
    【SpringBoot DB系列】Mybatis多数据源配置与使用
    【SpringBoot DB 系列】Mybatis-Plus 多数据源配置
    【SpringBoot DB 系列】Mybatis 基于 AbstractRoutingDataSource 与 AOP 实现多数据源切换
    【基础系列】ConfigurationProperties 配置绑定中那些你不知道的事情
    Spring 工具类之基本元素判断
  • 原文地址:https://www.cnblogs.com/jiayith/p/3871370.html
Copyright © 2020-2023  润新知