prodotto cartesiano di due spazi vettoriali

Aug 16 2020

Qualche giorno fa ho trovato un problema interessante che recita quanto segue:

Dati due spazi vettoriali genera l'insieme risultante del suo prodotto cartesiano. \begin{gather} \text{Lascia: } \mathcal{V}, \mathcal{W} \text{ spazi vettoriali}\\ \mathcal{V} \times \mathcal{W} = \{ (v,w ) \mid v \in \mathcal{V} \land w \in \mathcal{W} \} \end{gather}

  • Suggerimento 1: Uno spazio vettoriale è un insieme di elementi chiamati vettori che soddisfano alcune proprietà
  • Suggerimento 2: Progettare la soluzione per spazi vettoriali finiti
  • Suggerimento 1: si consiglia di utilizzare strutture
  • Vincolo: è vietato utilizzare qualsiasi classe stl

Ho risolto questo problema con il prossimo approccio:

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;
}

Come potrei migliorare questo codice se possibile?

Grazie.

Risposte

2 cauon Aug 18 2020 at 15:28
  1. const-correttezza
  2. utilizzare i riferimenti a favore dei puntatori ove possibile
  3. Il fatto di lasciare l'obbligo di liberare la memoria che allocate al chiamante non è generalmente una buona pratica
  4. uno schema comune nel tuo codice è che hai puntatori agli array e alla loro lunghezza - perché non creare una struttura per raggrupparli?
  5. prova a utilizzare iteratori e range-based-for-loop quando non hai davvero bisogno dell'indice (cosa che non hai nel tuo esempio)
  6. poiché non ci interessa davvero il tipo di elementi in uno spazio vettoriale, potresti utilizzare i modelli per generalizzare il tuo algoritmo

E solo per vedere se sarebbe stato possibile, ho provato a creare una versione dell'algoritmo in fase di compilazione:

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;
}

puoi provare il codice qui:https://godbolt.org/z/e8GvEf