NOIP--算法实现 - 行排序 列排序 Column sort

        Introduction to Algorithm 算法导论第八章的Column sort是非常有趣的,相当复杂。

        要用C++是实现起来是很困难的,因为需要用到几大块的小算法,才能实现。

第一是行间排序,第二是行列变换,第三是前后移动元素,这些算法都组合起来,整个过程就变得很复杂了。

        这次我是用二维数组来实现的,也可以用vector实现同样的效果,感觉能用vector还是用vector吧。而且我把书中的列排序,改变成行排序了,因为C++的习惯还是行优先数组。

        下面是整个程序,程序还是挺大的,相对于一个普通算法来说的话。所以写这个程序也要很耐心,要有时间。

[cpp] view plain copy print?

  1. #include<iostream>  

  2.   

  3. using namespace std;  

  4.   

  5. const int COLUMNS = 18;  

  6. const int ROWS = 3;  

  7.   

  8. template<typename T>  

  9. void compareExchange(T& a, int i, int j)  

  10. {  

  11.     if(a[i]>a[j])  

  12.         swap((a[i]), (a[j]));  

  13.     //cout<<a[i]<<" "<<a[j]<<endl;  

  14. }  

  15.   

  16. template<typename T>  

  17. void insertionSort(T& a, int n)  

  18. {  

  19.     for(int j=1; j<n; j++)  

  20.         for(int i=j-1; i>=0; i--)  

  21.         {  

  22.             compareExchange(a, i, i+1);  

  23.         }  

  24. }  

  25.   

  26. template<typename T>  

  27. void rowSort(T (&a)[ROWS][COLUMNS])  

  28. {  

  29.     int s=ROWS, c=COLUMNS;  

  30.     //Handle the enter data, make sure it fit this algorithm requirements  

  31.     bool flag = true;  

  32.     if((c%2) != 0)  

  33.     {  

  34.         cerr<<"Error: Columns c must be even!"<<endl;  

  35.         flag = false;  

  36.     }  

  37.     if((c%s) != 0)  

  38.     {  

  39.         cerr<<"Error: Rows s must be a divisor of columns c!"<<endl;  

  40.         flag = false;  

  41.     }  

  42.     if(!(c>=2*s*s))  

  43.     {  

  44.         cerr<<"Warning: Columns c should be >= rows 2*s*s, "  

  45.             <<"or you may not get the correct answer!"<<endl;  

  46.     }  

  47.     if(!flag) return;  

  48.   

  49.     //Sort the rows' elements, using insertion sort algorithm  

  50.     for(int i=0; i<s; i++)  

  51.     {  

  52.         insertionSort(a[i], c);  

  53.     }  

  54.       

  55.     //Change elements of row to column  

  56.     int n = 0;  

  57.     int m = 0;  

  58.     T aTemp[ROWS+1][COLUMNS];  

  59.     for(int i=0; i<s; i++)  

  60.         for(int j=0; j<c; j++)  

  61.         {  

  62.             if(n<s)  

  63.             {  

  64.                 aTemp[n][m] = a[i][j];  

  65.                 n++;  

  66.             }           //或者也可以把j++放到这里面,n++对应到j++  

  67.             else  

  68.             {  

  69.                 n=0;  

  70.                 m++;  

  71.                 j--;        //非常容易忽略的地方,一不留神就没有考虑到要倒退一个数字了。  

  72.                 //一定要在脑子多走几次比较新的逻辑,否则非常容易忽略细节的地方,导致出错。  

  73.                 //会浪费很多时间的。  

  74.             }         

  75.         }  

  76.   

  77.     //Sort the aTemp rows' elements, using insertion sort algorithm  

  78.     for(int i=0; i<s; i++)  

  79.     {  

  80.         insertionSort(aTemp[i], c);  

  81.     }  

  82.   

  83.     //Change elements of row to column  

  84.     n = 0;  

  85.     m = 0;  

  86.     for(int j=0; j<c; j++)  

  87.         for(int i=0; i<s; )  

  88.         {  

  89.             if(m<c)  

  90.             {  

  91.                 a[n][m] = aTemp[i][j];  

  92.                 m++;  

  93.                 i++;  

  94.             }//把i和m放在同一个{}里面,这样保证两个下标同步,否则会出现掉值  

  95.             else  

  96.             {  

  97.                 m=0;  

  98.                 n++;  

  99.             }         

  100.         }  

  101.   

  102.     //Sort the rows' elements, using insertion sort algorithm  

  103.     for(int i=0; i<s; i++)  

  104.     {  

  105.         insertionSort(a[i], c);  

  106.     }  

  107.   

  108.     for(int i=0; i<s+1; i++)  

  109.         for(int j=0; j<c; j++)  

  110.             aTemp[i][j] = 0;    //Supposed 0 is our minimum value.   

  111.                             //You can chenge to minus unlimit if need arise;  

  112.   

  113.     //move every elements back to half of columns position  

  114.     int tempIndex = 0;  

  115.     int halfC = c/2;  

  116.     for(int i=0; i<s; i++)  

  117.         for(int j=0; j<c; j++)  

  118.         {  

  119.             tempIndex = i*c+j+halfC;  

  120.             n = tempIndex/c;  

  121.             m = tempIndex%c;  

  122.             aTemp[n][m] = a[i][j];  

  123.         }  

  124.   

  125.     //Sort the rows' elements  

  126.     for(int i=0; i<s+1; i++)  

  127.     {  

  128.         insertionSort(aTemp[i], c);  

  129.     }  

  130.   

  131.     //move every elements half of columns position  

  132.     for(int i=0; i<s; i++)  

  133.         for(int j=0; j<c; j++)  

  134.         {  

  135.             tempIndex = i*c+j+halfC;  

  136.             n = tempIndex/c;  

  137.             m = tempIndex%c;  

  138.             a[i][j] = aTemp[n][m];  

  139.         }  

  140.     for(int i=halfC; i<c; i++)  

  141.         a[s-1][i] = aTemp[s][i];  

  142. }  

  143.   

  144. void test()  

  145. {  

  146.     //初始化数组  

  147.     double a[ROWS][COLUMNS] =   

  148.     {{32., 12., 0.7, 5., 0.1, 0.7, 0.8,0.7, 99., 0.4, 1., 2.5, 3.6, 5., 9., 12., 19.,953},  

  149.      {0.2, 0.8, 4., 8., 2., 0.8, 56.,0.3, 0.8, 0.4, 8., 7.5, 3.9, 5., 111., 52., 19.,39},  

  150.      {0.25, 0.3, 2., 9., 0.2, 0.78, 0.6,0.37, 0.83, 0.3, 8., 6.5, 9.6, 5., 181., 72., 19.,351}};  

  151.   

  152.     //排序前  

  153.     for(int i=0; i<ROWS; i++)  

  154.     {  

  155.         for(int j=0; j<COLUMNS; j++)  

  156.         {  

  157.             cout<<a[i][j]<<"\t";  

  158.         }  

  159.     }  

  160.     cout<<endl<<endl;  

  161.   

  162.     //调用排序函数  

  163.     rowSort(a);   

  164.       

  165.     //排序后  

  166.     for(int i=0; i<ROWS; i++)  

  167.     {  

  168.         for(int j=0; j<COLUMNS; j++)  

  169.         {  

  170.             cout<<a[i][j]<<"\t";  

  171.         }  

  172.     }  

  173.     cout<<endl;  

  174.   

  175. }  

  176.   

  177. int main()  

  178. {  

  179.     test();  

  180.     return 0;  

  181. }  


总结:

        个人觉得能不用普通c数组还是不要用普通数组,因为下标,内存处理等都非常麻烦,非常耗时。还是用vector等STL的标准容器会大大减少出错的几率。

逻辑问题也很重要,一不留神逻辑上就会出错,即便是能运行,那么结果也是不正确的,这样debug会花费很多时间。

 

NOIP信息学视频地址

视频地址

链接:https://pan.baidu.com/s/1tHo1DFMaDuMZAemNH60dmw 
提取码:7jgr

posted @ 2020-10-27 11:18  tianli3151  阅读(203)  评论(0编辑  收藏  举报