hasil kali kartesius dari dua ruang vektor

Aug 16 2020

Beberapa hari yang lalu saya menemukan masalah menarik yang berbunyi sebagai berikut:

Diberikan dua ruang vektor menghasilkan himpunan yang dihasilkan dari produk kartesiannya. \ begin {kumpulkan} \ text {Let:} \ mathcal {V}, \ mathcal {W} \ text {be vektor spasi} \\ \ mathcal {V} \ times \ mathcal {W} = \ {(v, w ) \ mid v \ in \ mathcal {V} \ land w \ in \ mathcal {W} \} \ end {kumpulkan}

  • Petunjuk 1: Ruang vektor adalah himpunan elemen yang disebut vektor yang menyelesaikan beberapa properti
  • Petunjuk 2: Rancang solusi untuk ruang vektor berhingga
  • Tip 1: Direkomendasikan untuk menggunakan struktur
  • Batasan: Anda dilarang menggunakan kelas stl apa pun

Saya memecahkan masalah ini dengan pendekatan selanjutnya:

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

Bagaimana saya dapat meningkatkan kode ini jika memungkinkan?

Terima kasih.

Jawaban

2 cauon Aug 18 2020 at 15:28
  1. const-benar
  2. gunakan referensi yang mendukung petunjuk jika memungkinkan
  3. Fakta bahwa Anda meninggalkan kewajiban untuk membebaskan memori yang Anda alokasikan untuk penelepon umumnya bukanlah praktik yang baik
  4. pola umum dalam kode Anda adalah Anda memiliki pointer ke array dan panjangnya - mengapa tidak membuat struktur untuk menggabungkannya?
  5. coba gunakan iterator dan range-based-for-loops ketika Anda tidak benar-benar membutuhkan indeks (yang tidak Anda lakukan dalam contoh Anda)
  6. karena kami tidak terlalu peduli tentang jenis elemen dalam ruang vektor, Anda dapat menggunakan templat untuk menggeneralisasi algoritme Anda

Dan hanya untuk melihat apakah itu mungkin, saya mencoba membuat versi waktu kompilasi dari algoritme:

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

Anda dapat mencoba kodenya di sini: https://godbolt.org/z/e8GvEf