1

時々、マトリックススタイルのデータ構造を生成するために次のコードを使用します

typedef double myType;

typedef struct matrix_t{                                                             |Compilation started at Mon Apr  5 02:24:15
  myType **matrix;                                                                   |
  size_t x;                                                                          |gcc structreaderGeneral.c -std=gnu99 -lz
  size_t y;                                                                          |
}matrix;                                                                             |Compilation finished at Mon Apr  5 02:24:15
                                                                                     |
                                                                                     |
matrix alloc_matrix(size_t x, size_t y){                                             |
  if(0)                                                                              |
    fprintf(stderr,"\t-> Alloc matrix with dim (%lu,%lu) byteprline=%lu bytetotal:%l\|
u\n",x,y,y*sizeof(myType),x*y*sizeof(myType));                                       |
                                                                                     |
  myType **m = (myType **)malloc(x*sizeof(myType **));                               |
  for(size_t i=0;i<x;i++)                                                            |
    m[i] =(myType *) malloc(y*sizeof(myType *));                                     |
                                                                                     |
  matrix ret;                                                                        |
  ret.x=x;                                                                           |
  ret.y=y;                                                                           |
  ret.matrix=m;                                                                      |
  return ret;                                                                        |
} 

そして、マトリックスのエントリに別の種類のタイプが必要な場合は、それに応じてtypedefを変更します。

ここで、異なるタイプの2つのマトリックスが必要です。簡単な解決策は、コードをコピーして貼り付けることですが、より一般的な実装を行う方法はあります。

ありがとう

編集:私はそれがc++ではなくcにあることを明確にする必要があります。それを明確にしないでごめんなさい。

4

3 に答える 3

3

Cでは?面倒ですが、マクロマジックで可能です。(ところで、C ++がより良い選択になるところまで来ています)。

#define DECL_MATRIX(type,name) \
    typedef struct matrix_##type##_t {             \
        type **matrix;                             \
        size_t x;                                  \
        size_t y;                                  \
    } name;                                        \
    name alloc_##name(size_t x,size_t y)

#define DEFINE_MATRIX_OPS(type,name) \
    struct matrix_##type##_t                       \
    alloc_##name(size_t x, size_t y) {             \
        size_t i;                                  \
        struct matrix_##type##_t ret;              \
        type **m;                                  \
                                                   \
        m = (type **)malloc(x*sizeof(type *));     \
        for(size_t i=0;i<x;i++)                    \
            m[i] =(type *) malloc(y*sizeof(type)); \
        ret.x=x;                                   \
        ret.y=y;                                   \
        ret.matrix=m;                              \
        return ret;                                \
    }

次に、次のように使用します。

// At the top level of the file
DECL_MATRIX(double, dmat);
DECL_MATRIX(int, imat);
DEFINE_MATRIX_OPS(double, dmat);
DEFINE_MATRIX_OPS(int, imat);

// In a function
dmat d = alloc_dmat(3,3);
imat i = alloc_imat(2,6);

設計上の注意として、固定サイズのマトリックスでは、要素のメモリを単一のブロックとして割り当て、少しの計算を使用して要素にインデックスを付けることをお勧めします。したがって、代わりにary[a][b]を使用しますary[a*x_size+y]。必要に応じて、これをより多くのマクロにまとめることができますが、メモリ管理とアクセスの両方の点ではるかに効率的です。

于 2010-04-05T12:25:20.610 に答える
1

1回限りのプロジェクトには非常に単純なマトリックスが必要で、これをノックアップしました。それは私が生産品質と呼ぶものではありませんが、それはあなたにいくつかのアイデアを与えるかもしれません:

template <typename T>
class Matrix2D {

    public:

        Matrix2D( unsigned int  width, unsigned int  height,
                            const T & v  = T() ) {
            if ( width == 0 || height == 0 ) {
                throw std::out_of_range( "Invalid Matrix2D size ");
            }
            for ( unsigned int x = 0; x < width; x++ ) {
                mData.push_back( std::vector<T>( height, v ) );
            }
        }

        T & operator()( unsigned int x, unsigned int y ) {
            if ( x >= Width() || y >= Height() ) {
                throw std::range_error( "Invalid Matrix2D index" );
            }
            return mData[x][y];
        }

        const T & operator()( unsigned int x, unsigned int y ) const {
            if ( x >= Width() || y >= Height() ) {
                throw std::range_error( "Invalid Matrix2D index" );
            }
            return mData[x][y];
        }


        void Clear( const T & v  = T() ) {
            for ( unsigned int x = 0; x < Width(); x++ ) {
                for ( unsigned int y = 0; y < Height(); y++ ) {
                    mData[x][y] = v;
                }
            }
        }

        unsigned int Width() const {
            return mData.size();
        }

        unsigned int Height() const {
            return mData[0].size();
        }

        void DumpOn( std::ostream & os ) {
            for ( unsigned int y = 0; y < Height(); y++ ) {
                for ( unsigned int x = 0; x < Width(); x++ ) {
                    os << '[' << mData[x][y] << ']';
                }
                os << "\n";
            }
        }

    private:

        std::vector <std::vector  <T> > mData;
};
于 2010-04-05T09:53:31.730 に答える
0

以前のコメントで示唆されているように、線形メモリを使用した行メジャー行列:

template<typename T, unsigned int DIM>
class matrix {
    public:
        matrix<T,DIM>() {
            matrix(0);
        }
        matrix<T,DIM>(const T* v) {
            for (unsigned int i=0; i<DIM*DIM; ++i)
                value[i] = v[i];
        }
        matrix<T,DIM>(T v) {
            for (unsigned int i=0; i<DIM*DIM; ++i)
                value[i] = v;
        }
        T& operator[](int index) {
            assert(index >= 0 && index < (int)(DIM*DIM));
            return value[index];
        }

        // and so on...

    private:
        T value[DIM * DIM];
}
于 2010-04-05T11:52:51.023 に答える