2016-09-26 8 views
0

ユーザーの入力に基づいてデータを保存する必要があります。私のプログラムは、私がcinから得たint値に基づいて異なるデータ構造を作成する必要があります。例えばユーザー指定の寸法を持つ行列を作成する方法

、0格納スカラー値、1 - ベクトル、2 - 2dArray、3 - 3dArray、4 - 4Dアレイなど...

私の質問は、それが一部を書き込むことができるのかどうかでありますこれを行うコード。

これは混乱するかもしれないことは知っていますので、いくつか例を挙げておきます。

ユーザーが0 5を入力すると、私のプログラムはint変数を作成し、その中に5を格納する必要があります。

ユーザが1 5,7,6を入力した場合、私のプログラムはベクトル= {5,7,6}を作成する必要があります。

ユーザが2 2,3 1,2,3,4,5,6を入力した場合、私のプログラムは2次元配列a [2] [3]を作成し、そこに値を格納する必要があります。私は、ユーザーが持ってしようとしている次元の最大数を知っていたが、割り当ての目標は、任意の数の次元を指定することができるということであるならば、私は解決策を見つけ出すことができ

...

ヘルプしてください

+1

次元数の制限を定義しない限り、無限に再帰的になります(n次元配列は(n-1)次元配列の配列なので、不可能です。あなたがバインドを指定しない限り、無限に再帰的な型定義が必要です)。あなたができることは、1次元配列(またはベクトル)を使用してインデックスを管理して、求めている動作をエミュレートすることです。実際には、10以上の次元が必要とされる現実世界のアプリケーションはほとんどなく、そのような配列のメモリ使用量は、とにかに利用可能なメモリをすぐに超えてしまいます。 – Peter

+0

私はエミュレーションについても考えていました。もっと詳しく記述できますか?あなたはそれをどのように実装しますか? – kozouu

+0

次元の積に等しいサイズの配列を割り当てます。それは、多次元配列が有する要素の数を有する。一連のインデックスと1次元配列のインデックスとの間のマッピングを実行します。 – Peter

答えて

1

いくつかの要件を緩和することができます(「cinから取得したint値に基づいて異なるデータ構造を作成する」)。これは単なるスケッチであり、完全な答えではありませんが、うまくいけばそれはあなたを軌道に乗せるでしょう。ストレージへ

アクセス:

あなたは所望のタイプの単一の配列に数値を格納し、インデックスマッピング機能を介してそれらへのアクセスをラップする必要があります。 例えば、2Dに、そのような機能は

int indexIn2D(uint rowCol[2], int rowCount) { 
    // rowCol[0] - is row index, rowCol[1] is col index 
    return rowCol[0]*rowCount + rowCol[1]; 
} 

float* values=new float[numRows*numCols]; 

// I want the element at (i,j) 
float& myIJElement=values[indexIn2D({i,j}, numRows)]; 

ストレージの

// suppose I'm storing a 3D matrix with [3 slices, 4 rows, 5 columns] 
// as a 1D array and I want the element at [x,y,z] - what's it would be 
// the position of that element in my 1D array? 
// - fill coodIndex[3] with {x,y,z} 
// - pass nDim=3 
// - the dimSignature will be {3 /*slices*/, 4 /*rows*/, 5 /*columns*} 
int indexInND(uint coordIndex[], uint numDim, uint[] dimSignature) { 
    int ret=coordIndex[0]; 
    for(uint i=0; i<numDim-; i++) { 
     ret=ret*dimSignature[i]+coordIndex[i+1]; 
    } 
    return ret; 
} 

変異体様タイプの行に何かを必要とするN次元にこれを変形ある

さて、私たちはすでに、 "N-dimブロック"全体をターゲットタイプの一次元配列として格納することを知っています。あなたはプレーンを使用することができます

template <typename NumType> class VectNStorage { 
    std::vector<NumType> storage; 
    std::vector<uint> dimSignature; 
protected: 
    size_t indexMapping(const std::vector<uint>& indices) { 
    size_t ret=indices[0]; 
    for(uint i=0; i<this->dimSignature.size()-1) { 
     ret=ret*this->dimSignature[i]+indices[i+1]; 
    } 
    return ret; 
    } 
public: 
    VectNStorage(const std::vector<uint> dimsDef) : storage(), dimSignature(dimsDef) { 
    uint howMany=1; 
    for(auto d : this->dimSignature) { 
     howMany*=d; 
    } 
    this->storage.resize(howMany); 
    std::fill(this->storage.begin(), this->storage.end(), 0); 
    } 

    NumType& at(const std::vector<uint>& indices) { 
    return this->storage[this->indexMapping(indices)]; 
    } 
} 
+0

hmmm、あなたのコードで何が起こっているのか分かりません... – kozouu

+0

1. 2D配列を1Dベクトルにどのようにマッピングしますか?行をとり、順番に入れてください。 2. nDimではどのようにしていますか?まあ、最後の2つのディムを取って、1のように線形化すると、nDim-1配列が得られます。単一の1Dアレイが完成するまでこれを繰り返します。 –

+0

@kozouuはっきりしていますか? –

1
  1. ユーザー入力の読み方を知っていますか?そうでない場合は、まずC++でそれを行う方法を理解してください。
  2. ユーザー入力から1つの変数を読み込みます。この変数は、作成する構造のタイプを示します。 (ヒント、intを使用)、ユーザが入力したものを参照してください(ヒント、初期タイプに基づいてif() {} else if() {}など
  3. を使用し、適切な構造を構築し、例えば、すべての種類を作成するヒントし
  4. を使用して、適切な検査を、 ,struct Vector{}など
  5. ユーザー入力の残りの部分を読み込むために作成した各構造体でread()メソッドを呼び出します(ユーザー入力を分割するには、何らかの形式を使用する必要があります)。文字列トークン化)
  6. サポートしていないタイプを拒否します。
0

:だから私たちは次のようにポインタの使用を作るとstdために私たちの "ストレージ" 何か ​​

のようなフォールバックFOMのバリアントを持っている::ベクトル

することができますすべてのタイプのユーザ入力に対してstd::vector。あなたが必要とするのは、インデックスのk-sizeベクトルを単純配列でインデックスする関数f(x)です。例えば

:X - K-サイズインデックスベクトル、sは - 寸法オブジェクト - K-サイズ寸法サイズベクトル

k = 1 -> f1(x,s) = x1; 
k = 2 -> f2(x,s) = x2*s2 + x1; 
k = 3 -> f3(x,s) = x3*s3*s2 + x2*s2 + x1 = x3*s3*s2 + f2(x2,x1,s2,s1); 
k = 4 -> f4(x,s) = x4*s4*s3*s2 + f3(x3,x2,x1,s3,s2,s1); 

最後の乗算器が座標(1、K)の容積です。 また、座標の数値は0から始まると考えます。

これは簡単な実装が可能な再帰関数のようです。あなたは(k - 1)次元オブジェクトのシフト、配列からポップ座標を計算し、関数自体を再び呼び出す必要があります。

+0

これは実行可能に見えますが、kサイズのインデックスベクトルとkサイズのディメンションサイズベクトルはどういう意味ですか?再帰をより詳細に記述できますか? – kozouu

+0

@kozouuあなたのデータ構造に 'k'次元がある場合、この構造体の要素に対処するために' k'インデックスが必要です。これはkサイズのインデックスであり、 'k'インデックスを表すためにベクトルを使うのは当然です。データ構造のサイズと同じです。 'k'サイズを与える各次元のサイズを決定する必要があります。また、ベクトルとして格納することもできます。 –

+0

@SemyonBurov再帰の必要はありません(何が起こっているのか知的な実現のためではありません)。インデックスマッピングの式は、多項式の値の計算に似ています。 –

関連する問題