3

割り当てられたメモリを使用して、特定の行列を転置するプログラムを作成しています。この関数は、正方行列NxN(rows == cols)で完全に機能しますが、MxN行列(rows!= cols)でクラッシュします。助けてください

void transpose(int **matrix, int *row, int *col)
{
    // dynamically allocate an array
    int **result;
    result = new int *[*col]; //creates a new array of pointers to int objects
    // check for error
    if (result == NULL)
    {
        cout << "Error allocating array";
        exit(1);
    }
    for (int count = 0; count < *col; count++)
    {
        *(result + count) = new int[*row];
    }

    // transposing
    for (int i = 0; i<*row; i++)
    {
       for (int j = i+1; j<*col; j++)
       {
        int temp = *(*(matrix + i) + j);
        *(*(matrix + i) + j) = *(*(matrix + j) + i);
        *(*(matrix + j) + i) = temp;
       }
    }

    for (int i = 0; i<*row; i++)
    {
       for (int j = 0; j<*col; j++)
       {
          *(*(result + i) + j) = *(*(matrix + i) + j);
          cout << *(*(result + i) + j) << "\t";
       }
       cout << endl;
    }
}
4

2 に答える 2

5

台詞:

for (int i = 0; i<*row; i++)
{
   for (int j = i+1; j<*col; j++)
   {
    int temp = *(*(matrix + i) + j);
    *(*(matrix + i) + j) = *(*(matrix + j) + i);
    *(*(matrix + j) + i) = temp;
   }
}

が問題です。問題は、行列のインデックスが i の次に j であり、j の次に i ではなく、while ループの 2 行目と 3 行目で行っていることです。行列が 2x3 行列であることをイメージしてから、行列[2][3] = 行列[3][2] を実行しようとしますが、行列[3][2] は存在しません。

このループで結果を直接初期化するのが最善です。

for (int i = 0; i<*row; i++)
   for (int j = 0; j<*col; j++)
     result[j][i] = matrix[i][j];

次に、以下のように出力するか、必要に応じて行列を削除して行列を結果に再割り当てできます。私の全体の転置関数は次のコードになりました (row と col は int へのポインタである必要はありません。値渡しは問題ありません。また、行列へのアクセスには配列の添え字を使用する必要があります。これは、より適切なスタイルであるためです)。

void transpose(int **matrix, int row, int col)
{
  // dynamically allocate an array
  int **result;
  result = new int *[col]; //creates a new array of pointers to int objects
  for (int i = 0; i < col; i++)
    result[i] = new int[row];

  // transposing
  for (int i = 0; i<row; i++)
   for (int j = 0; j<col; j++)
     result[j][i] = matrix[i][j];

  //output resulting matrix
  for (int i = 0; i<col; i++) {
   for (int j = 0; j<row; j++)
    cout << result[i][j] << "\t";
   cout << endl;
  }
}
于 2013-02-13T05:34:43.023 に答える
1

行列を「その場で」転置しようとしています:

( (行列 + i) + j) = ( (行列 + j) + i);

あなたはこれをすべきではありません。列数が に割り当てられた行数より大きい場合、割り当てられてmatrixいないメモリを読み書きします。

私見、マトリックス全体を連続メモリに保存する方が良いでしょう。別の部分ではありません。このようにすると、コードは次のようになります。

void transpose( int *matrix, int row, int col )
{
    for ( int i = 0; i < row; i++ )
    {
       for ( int j = i + 1; j < col; j++ )
       {
           int temp = matrix[ i * col + j ];
           matrix[ i * col + j ] = matrix[ j * col + i ];
           matrix[ j * col + i ] = temp;
       }
    }
}

この割り当ての唯一のマイナス点は、 のような要素をアドレス指定できないことmatrix[ i ][ j ]だけmatrix[ i + col + j ]です。プラスは次のとおりです。1)メモリの割り当て/割り当て解除が簡単(matrix = new int[ col * row ]およびdelete [] matrix)2)要素へのアクセスが少し高速(それらの連続的な場所のため)

最後に、私はそれを見るのが最善の方法だと思いますstd::vector。必要に応じて、ベクトルを使用してどのように機能するかをお見せします

于 2013-02-13T05:39:11.033 に答える