두 벡터 공간의 데카르트 곱
며칠 전 나는 다음과 같은 흥미로운 문제를 발견했습니다.
두 개의 벡터 공간이 주어지면 데카르트 곱의 결과 집합이 생성됩니다. \ begin {gather} \ text {Let :} \ mathcal {V}, \ mathcal {W} \ text {be vector spaces} \\ \ 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
- 상수 정확성
- 가능한 경우 포인터 대신 참조를 사용하십시오.
- 호출자에게 할당 한 메모리를 해제 할 의무를 남겨 두는 것은 일반적으로 좋은 습관이 아닙니다.
- 코드의 일반적인 패턴은 배열과 길이에 대한 포인터가 있다는 것입니다. 배열을 묶을 수있는 구조를 만드는 것은 어떻습니까?
- 인덱스가 실제로 필요하지 않을 때 반복기와 범위 기반 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