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
- const-corrección
- use referencias a favor de punteros cuando sea posible
- 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
- 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?
- intente hacer uso de iteradores y bucles basados en rango cuando realmente no necesita el índice (que no necesita en su ejemplo)
- 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