Generate the Cartesian Product of 2 vectors In-Place?

前端 未结 4 567
后悔当初
后悔当初 2021-01-25 08:21

If I want to get the Cartesian Product of these two vectors:

vector final{\"a\",\"b\",\"c\"};
vector temp{         


        
相关标签:
4条回答
  • 2021-01-25 09:01

    Try the function cartesian:

    #include <vector>
    #include <string>
    
    using namespace std;
    
    void cartesian(vector<string>& f, vector<string> &o) {
    int oldfsize = f.size();
    f.resize(oldfsize * o.size());
    for (int i = o.size() - 1; i>=0; i--) {
      for (int j = 0; j < oldfsize; j++) {
         f[i*oldfsize + j] = f[j] + o[i];
      }
     }
    }
    
    
    int main() 
    {
    vector<string> f{"a","b","c"};
    vector<string> temp{"1","2"};
    cartesian(f, temp);
    for (auto &s: f) {
      printf("%s\n", s.c_str());
     }
    }
    
    0 讨论(0)
  • 2021-01-25 09:04

    You may try the following approach

    #include <iostream>
    #include <vector>
    #include <string>
    
    int main() 
    {
        std::vector<std::string> final{ "a", "b", "c" };
        std::vector<std::string> temp{ "1", "2" };
    
        auto n = final.size();
    
        final.resize( final.size() * temp.size() );
    
        for ( auto i = n, j = final.size(); i != 0; --i )
        {
    
            for ( auto it = temp.rbegin(); it != temp.rend(); ++it )
            {
                final[--j] = final[i-1] + *it; 
            }
    
        }
    
        for ( const auto &s : final ) std::cout << s << ' ';
        std::cout << std::endl;
    
        return 0;
    }
    

    The program output is

    a1 a2 b1 b2 c1 c2 
    
    0 讨论(0)
  • 2021-01-25 09:21

    This is just a personal preference option to Vald from Moscow's solution. I think it may be faster for dynamic arrays because there would be less branching. But I haven't gotten around to writing a timing test bench.

    Given the inputs vector<string> final and vector<string> temp:

    const auto size = testValues1.first.size();
    
    testValues1.first.resize(size * testValues1.second.size());
    
    for (int i = testValues1.first.size() - 1; i >= 0; --i){
        testValues1.first[i] = testValues1.first[i % size] + testValues1.second[i / size];
    }
    

    EDIT:

    Nope, this solution is slower not faster: http://ideone.com/e.js/kVIttT

    And usually significantly faster, though I don't know why...

    In any case, prefer Vlad from Moscow's answer

    0 讨论(0)
  • 2021-01-25 09:22

    This works for me:

    void testCartesianString(vector<string>& final,
                             vector<string>const& temp)
    {
       size_t size1 = final.size();
       size_t size2 = temp.size();
    
       // Step 1.
       // Transform final to : {"a","a","b","b","c","c"}
       final.resize(size1*size2);
       for ( size_t i = size1; i > 0; --i )
       {
          for ( size_t j = (i-1)*size2; j < i*size2; ++j )
          {
             final[j] = final[i-1];
          }
       }
    
       // Step 2.
       // Now fix the values and
       // change final to : {"a1","a2","b1","b2","c1","c2"}
       for ( size_t i = 0; i < size1; ++i )
       {
          for ( size_t j = 0; j < size2; ++j )
          {
             final[i*size2+j] = final[i*size2+j] + temp[j];
             cout << final[i*size2+j] << " ";
          }
          cout << endl;
       }
    }
    
    0 讨论(0)
提交回复
热议问题