Cartesian Product in c++

我的未来我决定 提交于 2019-11-30 10:56:33

Here is an simple example of implementing Cartesian product using vector. Vectors are much better choice as we do not need to worry about its size as it dynamically changes it.

#include <iostream>
#include <vector>
#include <utility>
using namespace std;

int main() {
    int M[2]= {1,2};
    int J[3] = {0,1,2};
    vector<pair<int,int>> C;

    for (int i = 0; i < sizeof(M)/sizeof(M[0]); i++)
    {
        for (int j = 0; j < sizeof(J)/sizeof(J[1]); j++)
        {
            C.push_back(make_pair(M[i],J[j]));
        }  
    }

    /*
    for (vector<int>::iterator it = C.begin(); it != C.end(); it++)
    {
        cout << *it << endl;
    }

    */

    for (int i = 0; i < C.size(); i++)
    {
        cout << C[i].first << "," << C[i].second << endl;
    }
}

Here is the link where I implemented the above code. Although I wouldn't post solution directly relating to your question, links posted in the comments already contains answer which is why I posted.

#include <iostream>
#include <iterator>
#include <vector>
#include <utility>

template<typename Range1, typename Range2, typename OutputIterator>
void cartesian_product(Range1 const &r1, Range2 const &r2, OutputIterator out) {
    using std::begin; using std::end;

    for (auto i = begin(r1);i != end(r1); ++i) {
        for (auto j = begin(r2); j != end(r2); ++j) {
            *out++ = std::make_tuple(*i, *j);
        }
    }
}

int main() {
    std::vector<int> a{1,2,3};
    std::vector<char> b{'a','b','c','d','e','f'};

    std::vector<std::tuple<int, char>> c;
    cartesian_product(a, b, back_inserter(c));

    for (auto &&v : c) {
        std::cout << "(" << std::get<int>(v) << "," << std::get<char>(v) << ")";
    }
}

Prints:

(1,a)(1,b)(1,c)(1,d)(1,e)(1,f)(2,a)(2,b)(2,c)(2,d)(2,e)(2,f)(3,a)(3,b)(3,c)(3,d)(3,e)(3,f)

And you can also apply the function to your case:

template<typename T, int N> constexpr int size(T (&)[N]) { return N; }

int main() {
    int M[2] = {1,2};
    int J[3] = {0,1,2};

    std::tuple<int, int> product[size(M) * size(J)];

    cartesian_product(M, J, product);

    for (auto &&v : product) {
        std::cout << "(" << std::get<0>(v) << "," << std::get<1>(v) << ")";
    }
}

The output is:

(1,0)(1,1)(1,2)(2,0)(2,1)(2,2)

http://coliru.stacked-crooked.com/a/3ce388e10c61a3a4

I think using of c++ two-dimensional arrays is a very bad idea, but if you want, you probably could use this code

    #include <iostream>    
    int** cartesian_prod( int* s1, int* s2, int s1size, int s2size )
    {
        int ressize = s1size*s2size;
        int** res = new int*[ressize];
        for ( int i = 0; i < s1size; i++ )
            for ( int j = 0; j < s2size; j++ )
            {
                res[i*s2size+j] = new int[2];
                res[i*s2size+j][0] = s1[i];
                res[i*s2size+j][1] = s2[j];
            }
        return res;
    }
    int main() {
        int M[2]= {1,2};
        int J[3] = {0,1,2};
        int** res;
        int Msize = sizeof(M)/sizeof(M[0]);
        int Jsize = sizeof(J)/sizeof(J[1]);
        res = cartesian_prod(M, J, Msize, Jsize);
        for ( int i = 0; i < Msize*Jsize; i++ )
            std::cout << res[i][0] << " " << res[i][1] << std::endl;
        for (int i = 0; i < Msize*Jsize; i++)
            delete[] res[i];
        delete[] res;
        return 0;
    }

But it is much better to deal with std::vector - it much faster (in terms of development time) and will save you from many errors.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!