對於轉置,若是咱們不考慮轉置以後的元素順序,實際上只須要遍歷一遍整個三元組,交換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指針