2015-06-08 85 views
1

我有動態類型的方陣,正確分配刪除列和行的方陣用C

double **matrix; 

我希望從矩陣刪除「X」行和「X」一欄,以這種方式:

SOURCE MATRIX: 
1 2 3 4 
5 6 7 8 
9 10 11 12 
13 14 15 16 

我想刪除,例如,第二行/列。輸出必須是這樣的:

FINAL MATRIX: 
1 3 4 
9 11 12 
13 15 16 

我試着寫下並測試很多算法,但沒有成功。 我該怎麼辦?

+0

你必須做到這一點,或者你可以建立另一個矩陣? –

+0

這將是一個混亂的地方。 –

+0

我更喜歡這樣做:) – dogmaxpeppe

回答

1

好,要做到這一點,你必須認識到,在你的記憶矩陣實際上是列表的列表。 這意味着刪除列是從移除一行稍有不同:

假設你的語法是matrix[row][column];

void removeColumn(int** matrix, int col){ 
    MATRIX_WIDTH--; 
    //TODO check for empty matrix etc; 
    for(int i=0;i<MATRIX_HEIGHT; i++) 
    { 
    while(col<MATRIX_WIDTH) 
    { 
     //move data to the left 
     matrix[i][col]=matrix[i][col+1]; 
     col++; 
    } 
    matrix[i] = realloc(matrix[i], sizeof(double)*MATRIX_WIDHT); 
    } 
void removeRow(int** matrix, int row){ 
    MATRIX_HEIGHT--; 
    //TODO check for empty matrix etc. 
    free(matrix[row]); 
    while(row<MATRIX_HEIGHT) 
    { 
    //move data up 
    matrix[row] = matrix[row+1]; 
    row++; 
    } 
} 

所以removeColumn遍歷每一行,並刪除相應的項目,並removeRow正好可以free的行,並覆蓋它的指針。

請注意,您必須自己跟蹤矩陣大小的大小。在我使用的示例中,我使用了MATRIX_WIDTHMATRIX_HEIGHT,但是您必須爲此執行某些操作。 (也許一個結構與寬度高度和指針在它。)

+0

這個算法就像一個魅力!它在時間和空間上都很高效,而且它能夠滿足我的需求。謝謝,你讓我的一天:D – dogmaxpeppe

+0

我寧願'memmove()'代替每個'while()'循環,例如。用'memmove(matrix [i] + col,matrix [i] + col + 1,sizeof(int)*(MATRIX_WIDTH - col - 1))'替換'while(col duncan

+0

我測試了這個算法,所以,它不工作,因爲我希望。我對列有問題。 例如:如果我想要刪除第一行和第一列,它會刪除第一行但刪除LAST列。 也許有問題時,我叫功能? removeColumn((double **)G-> adjk,node,G-> num_nodes); removeRow((double **)G-> adjk,node,G-> num_nodes);我認爲這是同樣的事情 void removeColumn(double ** matrix,int col,int dim); void removeRow(double ** matrix,int row,int dim); – dogmaxpeppe

-1

我會做的是將這個矩陣分成5個區域。 1)要刪除的區域。 2)在刪除索引之前的「區域」(在你的示例矩陣中它只是1)。 3)在刪除索引之後的區域(在你的矩陣中它將是11,12,15,16)。 4)和5)剩餘的兩個「區域」。一個會是(3,4)另一個會(9,13)

只需爲5個區域中的每個區域創建條件並進行復制。

double** matrix = (double**)malloc(sizeof(double)*n*n); 
//fill in the matrix here 
double** copy (double**)malloc(sizeof(double)*(n-1)*(n-1)); 
int i; 
int j; 
int deleteNum; //what ever row you want to delete 
for(i = 0; i < n; i++){ 
    for(j = 0; j < n; j++){ 
     if(i < deleteNum && j < deleteNum){ 
      copy[i][j] = matrix[i][j]; 
     } 
     else if(deleteNum == i || deleteNum == j){ 
      //one of the rows/columns to be deletd 
      //basically skip 
     } 
     else if(i < deleteNum && j > deleteNum){ 
      copy[i][j-1] = matrix[i][j]; 
     } 
     else if(i > deleteNum && j < deleteNum){ 
      copy[i-1][j] = matrix[i][j] 
     } 
     else{ 
      copy[i-1][j-1] = matrix[i][j]; 
     } 
    } 
} 
+0

我不會推薦使用矩陣來實現圖。有(在我看來)使用鄰接表更多的好處。 – dimyr7

+0

這取決於應用程序 –

+0

確實,但它是爲大學考試:) – dogmaxpeppe

0

因爲我正在尋找類似的問題的答案,但矩陣存儲在線性空間這裏是我的解決方案(我在這裏使用列主要順序,但如果您使用的是行 - 主要它只需要很小的變化)

void removeRow(float * arrayToRemove, const int & currentRows, const int & currentCols, const int & row) 
{ 
    auto currDiff = 0; 
    auto step = currentRows; 
    auto elemNum = currentRows * currentCols; 

    for (int i = row, stepCounter = 0; i < elemNum; ++i, ++stepCounter) 
    { 
     if (stepCounter % step == 0) 
     { 
      ++currDiff; 
     } 
     else 
     { 
      arrayToRemove[i - currDiff] = arrayToRemove[i]; 
     } 
    } 
} 

void removeCol(float * arrayToRemove, const int & currentRows, const int & currentCols, const int & col) 
{ 
    auto destination = arrayToRemove + (col * currentRows); 
    auto source = arrayToRemove + ((col + 1) * currentRows); 
    const auto elemsNum = (currentCols - (col + 1)) * currentRows; 
    memcpy(destination, source, elemsNum * sizeof(float)); 
}