2012-01-25 16 views
2

最良の方法このスレッドは、c + +約多次元配列です。ダブル多次元配列、

私はいくつかのコードをc#からcppに移植する必要があります。私はこのようなコードを持っている:私は、配列の平野double配列を使用することを考えている

private double[,] B; 
... 
this.B = new double[states, symbols]; 
double[][, ,] epsilon = new double[N][, ,]; 
double[][,] gamma = new double[N][,]; 
... 
s += gamma[i][t, k] = ... 

を、それは非常に苦痛です。別の解決策は、二重のベクトルベクトル、またはカスタムMatrix2DとのMatrix3Dクラスだろうか?

それぞれの場合にはどのような方法が最適ですか?私が学んだこと



:C++の中

  • 多次元配列は偉大なトピックで、インターネットは資源がいっぱいです。さまざまな方法で処理することができます。そのうちのいくつかは本当に扱いにくく、他のいくつかはより速く書くことができます。

  • 私はそれに対処することで最良の方法は、アカウントにこのトピックを取り、いくつかのライブラリを使用することであると思います。それらの多くがあります:Armadillo(素敵なMATLABの構文変換)、Eigen私はより良い1つ、インストールしやすい、使いやすい、強力だと思います。 Boost::multi_arrayは別のもので、Boostは本当に有名なlibであり、トピックをどのように処理するかを見るだけで重要です。 Konrad Rudolph answerSTD with nested vectorsまたはthisは、別の解決策になる可能性がありますが、少し検索した後、私はあまりエレガントさえせずに、コードをより簡単かつ迅速に外部LIBSを考えています。

  • は、カスタムクラスを記述します。それは良い運動かもしれません。 peter answerまたはthisまたはthisは良いスタート地点であり、またthis post面白いですが、expeciallyこのgreat post blog from martin moene(私は今日読んだこのトピックで最高のエッセイの1つ)。私はsparse arrayのこの答えにも言及します。ここ

  • はStroustrup氏

  • から直接nice tutorialである私は、動的配列言う

+0

最後に、私は使用しているフレームワークに既に組み込まれていたので、私はブーストを使用しました! – nkint

答えて

2
class StateSymbols 
{ 
public: 
    StateSymbols(unsigned int states, unsigned int symbols) : 
    m_states(states), 
    m_stateSymbols(states * symbols) 
    { 
    } 

    double get(unsigned int state, unsigned int symbol) const 
    { 
     return m_stateSymbols[(m_states * symbol) + state]; 
    } 

private: 
    const unsigned int m_states; 
    std::vector<double> m_stateSymbols; 
}; 
+0

+1これも非常に良い解決策です。多次元行列を1次元ベクトルにマッピングすることは、クラスにカプセル化すると非常に意味があります。 –

+0

これはmatrix2Dクラスです。 matrix3Dはどうですか?つまりdouble [、、] – nkint

+0

@nkint 3次元ではそれを解決するのにあまり努力はしていません –

0

:-)多次元配列で素敵な時間を持っている:

double* *list; 
list = new double*[3]; //dimension1=3=row 
for(int i=0;i<3;i++) 
    list[i] = new double[2]; //dimension2 =2 =col 
list[0][0] = 1; 

//... 

for(int i=0;i<3;i++) 
    delete [] list[i]; 
delete [] list; 
+0

お返事ありがとうございます。二重[] [、]ガンマ? – nkint

+3

これは*悪い*解決策です。このような状況で手動メモリ管理を使用しないでください。 –

+0

?ベクトルを使う方が良いですか? – nkint

3

C++がノーを持っていますT[,]の直接の等価物です(もちろん、クラスに次のコードをカプセル化することで実装することもできます)。彼は読者に運動として残されています。

すべてのC++がサポートネストアレイ/ベクトル(C#で[][]に相当)です。だからあなたの最初のコードが適切に初期化ベクトル内のstatesコピーを外側のベクトルを初期化、ベクトルのベクトルを初期化

vector<vector<double> > B(states, vector<double>(symbols)); 

...に対応します。もちろん

これは、任意の複雑さに撮影することができますが、この時点でいくつかのtypedefは、コードをより分かりやすくするためにあります。

+0

あなたの答えは良い助言のようです。ちょうど2つのこと:1 - ダブルからの抽象化のためのテンプレート化の可能性? 2 - 私はcompletly行列(double [] []またはdouble [] [] [])を破棄する必要がありますか?私はそれが良いと簡単な解決策だと思った! – nkint

+1

@nkint 1-もちろんテンプレートを使って抽象化することもできます。しかし、C++ 0xより前のC++は、テンプレート化されたtypedefのようなものを知らない。それらをシミュレートするには、[テンプレートメタ機能](http://stackoverflow.com/a/26162/1968)に頼る必要があります。 2 - 行列を大きく扱っている場合は、ネストされたベクトルの周りにクラスラッパーを記述して、より直感的に使用できるようにするのが理にかなっています。しかし、とにかくそれをカプセル化するならば、メモリ消費量/パフォーマンスに関してネストされたベクトルより優れているPeter Woodの答えも見てください。 –

1

上の私の答えチェックアウト:それができますように、ヒープ上に連続したメモリ内の3D(他の寸法に一般)配列を割り当てるための基本的な機能Create3Dを定義

C++ Multi-dimensional Arrays on the Heap

A[i][j][k]アクセス演算子構文。