producto cartesiano de dos espacios vectoriales

Aug 16 2020

Hace unos días encontré un problema interesante que dice lo siguiente:

Dados dos espacios vectoriales generar el conjunto resultante de su producto cartesiano. \begin{reunir} \text{Sean: } \mathcal{V}, \mathcal{W} \text{ espacios vectoriales}\\ \mathcal{V} \times \mathcal{W} = \{ (v,w ) \mid v \in \mathcal{V} \land w \in \mathcal{W} \} \end{reunir}

  • Pista 1: Un espacio vectorial es un conjunto de elementos llamados vectores que cumplen algunas propiedades
  • Pista 2: Diseña la solución para espacios vectoriales finitos
  • Consejo 1: Se recomienda utilizar estructuras
  • Restricción: tiene prohibido usar cualquier clase stl

Resolví este problema con el siguiente enfoque:

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

¿Cómo podría mejorar este código si es posible?

Gracias.

Respuestas

2 cauon Aug 18 2020 at 15:28
  1. const-corrección
  2. use referencias a favor de punteros cuando sea posible
  3. El hecho de que dejes la obligación de liberar la memoria que asignas a la persona que llama generalmente no es una buena práctica
  4. un patrón común en su código es que tiene punteros a matrices y su longitud, ¿por qué no crear una estructura para agruparlos?
  5. intente hacer uso de iteradores y bucles basados ​​​​en rango cuando realmente no necesita el índice (que no necesita en su ejemplo)
  6. dado que realmente no nos importa el tipo de elementos en un espacio vectorial, podría usar plantillas para generalizar su algoritmo

Y solo para ver si sería posible, traté de crear una versión del algoritmo en tiempo de compilación:

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

Puedes probar el código aquí:https://godbolt.org/z/e8GvEf