C ++ декартово произведение множественных строк

У меня есть строки, хранящиеся в векторе как таковые: vector<string> ex = {"ab", "cd", "ef"},
Теперь мне нужно создать декартово произведение этих строк (количество строк в векторе, а также длина строк фиксирована!). Результат должен быть:

  ace
acf
ade
adf
bce
bcf
bde
bdf

Есть ли встроенная функция, которая уже существует для этого, или у вас есть какой-либо совет, как выполнить реализацию?

Отдельные буквы строк должны использоваться для декартового произведения, а не всей строки!

0

Решение

Я могу предложить этот способ с помощью библиотеки
https://cpplinq.codeplex.com/

#include <iostream>
#include <vector>
# include <algorithm>
# include <iterator>
# include <string>
# include <tuple>
# include <functional>
# include <cmath>
#include "cpplinq.hpp"using namespace cpplinq;

std::vector<std::string> simpleTransform(const std::vector<std::string> &ex);
int main()
{
std::vector<std::string> ex1(3);
ex1[0]="ab";
ex1[1]="cd";
ex1[2]="ef";

auto VS = simpleTransform(ex1);
std::copy(VS.begin(),VS.end(),std::ostream_iterator<std::string>(std::cout,"\n"));

return 0;
}

std::vector<std::string> simpleTransform(const std::vector<std::string> &ex)
{
size_t N = ex.size();
size_t M = ex[0].size();
std::vector<std::string> VS(pow(M,N));
size_t count=0;

std::function<void(size_t,std::vector<size_t>)> Var=
[&](size_t ind,std::vector<size_t> vec)
{
if(ind==0)
{
std::string r;
r.resize(N);
for(size_t j=0;j<N;j++)
r[j] = ex[j][vec[j]-1];

VS[count] =r;
count++;
return;
}
else
{
std::vector<size_t> newvec(vec);
auto temp = N-ind+1;
newvec.resize(temp);
range(1,M)>>for_each([&](int const & j){
newvec[temp-1]=j;
Var(ind-1,newvec);});
}
};
Var(N,std::vector<size_t>());

return VS;
}

Я не делал проверку входных данных.

2

Другие решения

Хорошо, я нашел решение. Возможно, он не самый лучший, и наверняка есть некоторые улучшения кода, но этого достаточно для моих целей и на тот случай, если кому-то это тоже нужно:

vector<string> getProducts(vector<string> s) {
int combinations = 1;
vector<string> res;
for (unsigned int i=0; i<s.size(); i++) {
combinations *= s.at(i).length();
}

for (unsigned int i=0; i<s.size(); i++) {
string cur = s.at(i);
int div = combinations / cur.length();
int count = 0;
for (unsigned int ch=0; ch<cur.length(); ch++) {
for (int len=0; len<div; len++) {
if (i==0) {
res.push_back(string(cur.substr(ch, 1)));
} else {
string tmp = res.at(count);
tmp.append(string(cur.substr(ch,1)));
res.at(count) = tmp;
}
count++;
}if ((ch == cur.length()-1) && (count <= res.size()-1) && i>0) {
ch = -1;
}
}
combinations = div;
}

return res;

}

0

Может быть, результат достижим с помощью std :: collect.

Нужна бинарная операция этой формы

std::vector<string> product(const std::vector<string> &init, string value)
{
std::string result ;
for (auto ch : value)
if (init.empty())
result.push_back(string(1, ch)) ;
else
for (auto str : init)
result.push_back(str + string(1, ch)) ;
return result ;
}

затем вызовите std :: аккумулировать (vect.begin (), vect.end (), std :: vector (), product)

-1
По вопросам рекламы [email protected]