对于转置,若是咱们不考虑转置以后的元素顺序,实际上只须要遍历一遍整个三元组,交换x和y的值就ok了。之因此须要快速转置算法是由于若是三元组在初始时是按照每一个三元组x的值从大到小排的,咱们但愿在转置后,其顺序依旧是按照x的值大小排列。ios
对于这个问题,咱们能够先统计y每一个取值的数量,接着咱们就可算出来对于每一个y转置成x后每一个x会有几个,即咱们能够知道咱们放置转置后的三元组的开始位置。
举个例子来讲,假设咱们有以下三元组:c++
//Origin matrix x | y | value ---------------- 1 4 0 1 2 1 1 1 -3 2 3 4 3 4 9 3 3 1 4 1 2
那么咱们能够遍历一遍得到y取1,2,3,4的数目分别为2,1,2,2。那么咱们转置后的三元组排列必定是这样的:算法
一个短下划线表明一个三元组 x=1 x=2 x=3 x=4 |_ _ | _ |_ _ |_ _
若是这样的话咱们就能够知道对于原矩阵中的每个三元组中,根据其y的取值咱们就能够对应找到咱们要放入的位置,即指向x取值开始的指针(xStart数组记录)。而后每在某一个指针指的区域中放入一个数就让指针向后移动一位。
经过这样咱们只须要遍历一遍原来的矩阵就能够获得转置好的矩阵了。数组
对于我以前提到的如何得到指向x取不一样值的指针,咱们须要两个辅助数组yCount & xStart.先获得yCount而后根据yCount来计算获得xStart即咱们想要的指针。spa
//Origin matrix /* x | y | value ---------------- 1 4 0 1 2 1 1 1 -3 2 3 4 3 4 9 3 3 1 4 1 2 */ #include<iostream> using namespace std; int yCount[100],xStart[100]; //two extra array class Node{ public: Node(){} int x; int y; int value; }; Node originMat[100]; Node transMat[100]; void getyCount(int n){ for(int i=0;i<n;i++){ yCount[originMat[i].y]++; } } void getxStart(int n){ for(int i=1;i<n;i++){ xStart[i]=xStart[i-1]+yCount[i-1]; } } void fastTransMat(int n){ getyCount(n); getxStart(n); for(int i=0;i<n;i++){ int start=xStart[originMat[i].y]++; //get the pos and pointer++ transMat[start]=originMat[i]; swap(transMat[start].x,transMat[start].y); } } void display(int n){ for(int i=0;i<n;i++){ cout<<transMat[i].x<<' '<<transMat[i].y<< ' '<<transMat[i].value<<endl; } } int main(void){ int n; cout<<"the number of originMat elements"<<endl; cin>>n; cout<<"input originMat with x|y|value"<<endl; for(int i=0;i<n;i++){ cin>>originMat[i].x>>originMat[i].y>>originMat[i].value; } fastTransMat(n); display(n); }
原始文章发布在个人博客loveSnowBest's blog指针