2つのベクトル空間のデカルト積
数日前、私は次のような興味深い問題を見つけました。
2つのベクトル空間が与えられると、そのデカルト積の結果セットが生成されます。\ begin {gather} \ text {Let:} \ mathcal {V}、\ mathcal {W} \ text {はベクトル空間} \\ \ mathcal {V} \ times \ mathcal {W} = \ {(v、w )\ mid v \ in \ mathcal {V} \ land w \ in \ mathcal {W} \} \ end {gather}
- ヒント1:ベクトル空間は、いくつかのプロパティを実現するベクトルと呼ばれる要素のセットです。
- ヒント2:有限ベクトル空間の解を設計する
- ヒント1:構造を使用することをお勧めします
- 制約:stlクラスの使用は禁止されています
私は次のアプローチでこの問題を解決しました:
struct vector_pair
{
double *vector_a;
double *vector_b;
size_t a_dimension;
size_t b_dimension;
};
struct cartesian_product_set
{
vector_pair *pairs;
size_t pairs_number;
};
cartesian_product_set vector_spaces_cartesian_product(double **space_v, size_t v_vectors,
size_t v_dimension, double **space_w, size_t w_vectors, size_t w_dimension)
{
cartesian_product_set product_set{new vector_pair[v_vectors * w_vectors], v_vectors * w_vectors};
for (size_t i = 0, j, k = 0; i < v_vectors; i++)
for (j = 0; j < w_vectors; j++)
product_set.pairs[k++] = vector_pair{space_v[i], space_w[j], v_dimension, w_dimension};
return product_set;
}
可能であれば、このコードをどのように改善できますか?
ありがとうございました。
回答
2 cauon
- const-correctness
- 可能な場合はポインタを優先して参照を使用する
- 発信者に割り当てたメモリを解放する義務を残すという事実は、一般的には良い習慣ではありません。
- コードの一般的なパターンは、配列とその長さへのポインターがあることです。配列をバンドルする構造を作成してみませんか?
- インデックスが本当に必要ない場合は、イテレータと範囲ベースのforループを利用してみてください(例では必要ありません)。
- ベクトル空間の要素のタイプはあまり気にしないので、テンプレートを使用してアルゴリズムを一般化できます。
そして、それが可能かどうかを確認するために、コンパイル時バージョンのアルゴリズムを考え出そうとしました。
template<typename T>
struct pair
{
T first;
T second;
};
template<std::size_t N, typename T>
struct cvp
{
pair<T> pairs[N];
};
template <typename T, size_t NV, size_t NW>
auto get_cvp(const T (&vs)[NV], const T (&ws)[NW])
{
cvp<NV*NW, T> result;
auto it_pairs = std::begin(result.pairs);
for (const auto v : vs) {
for (const auto w : ws) {
*(it_pairs++) = {v, w};
}
}
return result;
}
ここでコードを試すことができます: https://godbolt.org/z/e8GvEf