3

R データ フレームでできるように、C++ で C++ の 2 次元配列 (行列) を扱いたいと思います。つまり、行列のインデックス値を指定できるということです。

たとえば、自然な C++ 整数行列は次のようになります。

  0 1 2 3 4 ...
0 1 0 1 0 .
1 3 . . .
2 8 . .
3 . .
4 .
.
.
.

マトリックスでインデックスを指定したいので、たとえば次のようになります。

  5 7 8 13 24 ...
0 1 0 1 0 .
1 3 . . .
2 8 . .
6 . .
8 .
.
.
.

どんなアドバイスでも大歓迎です。

4

3 に答える 3

3

行列の列、行を切り替えたい場合は、いくつかの間接化を使用できます。

 indexTable[0][0] = 0; // map row index 0 to 0
 indexTable[1][0] = 5; // map column index 0 to 5

次のように使用します。

 value = matrix[indexTable[0][RowIndex]][indexTable[1][ColumnIndex];

または、この間接化を処理するクラスを作成できます。

于 2013-04-17T17:31:56.933 に答える
0

私はクラスを作成します

  • 指定された任意のインデックスを 0 ベースのインクリメンタル インデックスに変換します
  • 変換されたインデックスを使用して 2D 配列としてアクセスできるように、1D 配列をラップします

実際の例は次のようになります

#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <iterator>
#include <cassert>

using namespace std;

class DataFrame
{
  vector<int> data;

public:
  typedef vector<ssize_t> idx_t;
private:
  idx_t rowIdx;
  idx_t colIdx;

public:
  DataFrame(const idx_t &rowIdx, const idx_t &colIdx)
    : data(rowIdx.size() * colIdx.size())
    , rowIdx(rowIdx)
    , colIdx(colIdx)
  {
    assert(is_sorted(rowIdx.begin(), rowIdx.end()));
    assert(is_sorted(colIdx.begin(), colIdx.end()));
  }

  int& operator()(int i, int j)
  {
    idx_t::iterator itI, itJ;

    itI = lower_bound(rowIdx.begin(), rowIdx.end(), i);
    if(rowIdx.end() == itI || i != *itI) throw out_of_range("could not find specified row");
    itJ = lower_bound(colIdx.begin(), colIdx.end(), j);
    if(colIdx.end() == itJ || j != *itJ) throw out_of_range("could not find specified col");

    return data[distance(rowIdx.begin(), itI)*colIdx.size() +
      distance(colIdx.begin(), itJ)];
  }

  vector<int> & getData() { return data; }
};


int main()
{
  DataFrame::idx_t rI, cI;
  rI.push_back(3);
  rI.push_back(5);

  cI.push_back(2);
  cI.push_back(3);
  cI.push_back(10);

  DataFrame df(rI, cI);

  df(3,2) = 1;
  df(3,3) = 2;
  df(3,10) = 3;
  df(5,2) = 4;
  df(5,3) = 5;
  df(5,10) = 6;

  ostream_iterator<int> out_it(cout, ", ");
  copy(df.getData().begin(), df.getData().end(), out_it);
  cout << endl;

  return 0;
}

各行/列の任意のインデックスはベクトルで指定されます。ある程度のパフォーマンスを維持するために、コードではインデックスが単調に増加する必要があります。(C++11 を使用している場合、これは ctor でチェックされます。C++11 を使用していない場合、is_sorted関数はありません。また、このコードは、任意のインデックスの一意性を検証しません。)

データにアクセスすると、インデックスの各ベクトルに対してバイナリ検索が実行され、任意のインデックスに一致するベクトル内の位置が検索され、その位置が基になるデータに対応するインデックスとして使用されます。2D インデックスから 1D インデックスへの単純な変換があります。

それについて心配する必要がある場合は、悪いインデックスと良いインデックスのすべての組み合わせに対して、私のインデックス エラー チェックが正しいことを確認することをお勧めします。

アクセサー、さまざまなコンストラクターなどに関して、より堅牢性/機能を追加することはあなたに任せますconst。これを2次元以外の配列に一般化する場合は、任意のインデックスを0に変換するだけのクラスを作成することをお勧めします.ベースのインデックスであり、これにより、コードの繰り返しの一部が取り除かれます。map他の人が提案したようなものなど、任意のインデックスを 0 ベースのインデックスに変換する方法は他にもあります。ただし、その場合、 の作成者は、mapたとえば 10 個の列がある場合、[0, 10) の各インデックスがマップ内の値として 1 回だけ表示されるようにする必要があるなど、いくつかの問題があります。

于 2013-04-17T20:39:35.640 に答える