Given the following Python (from http://norvig.com/sudoku.html)
def cross(A, B):
"Cross product of elements in A and elements in B."
return [a+b for a in A for b in B]
cols = '123456789'
rows = 'ABCDEFGHI'
squares = cross(rows, cols)
This produces:
['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'B1', 'B2', 'B3', ...]
As an exercise, I want to do the same in C++. Currently I have:
#include <iostream>
#include <map>
#include <vector>
using std::string;
using std::vector;
static vector<string> cross_string(const string &A, const string &B)
{
vector<string> result;
for (string::const_iterator itA = A.begin(); itA != A.end(); ++itA) {
for (string::const_iterator itB = B.begin(); itB != B.end(); ++itB) {
char s[] = {*itA, *itB, 0};
result.push_back(string(s));
}
}
return result;
}
int main(int argc, char** argv)
{
const char digits[] = "123456789";
const char rows[] = "ABCDEFGHI";
vector<string> res = cross_string(rows, digits);
for (vector<string>::const_iterator it = res.begin();
it != res.end(); ++it) {
std::cout << *it << std::endl;
}
}
This works, but I was hoping there would be a better way. This also does only strings, whereas the python does any list…
Edit:
Thanks for all of the replies. I accepted the one that I understood best, but Alf’s answer was a close second. I note that all used C++11 and wonder whether as a novice at C++ I should adopt that directly instead of the learning the older standard. But that is perhaps best for another question.
Weirdly enough,
cross_productis missing from the C++ algorithms library. It can easily be added but as Jerry’s and Alf’s answers show, opinions differ on how to do it best. In fact, I’d do it different still. Jerry’s interface conforms to that of the other C++ algorithms but he didn’t abstract away the cross product operation, which I’d do thusly:The call, in your example, would then look as follows:
(Don’t I just love C++11? Yes, I do.)
In a proper library I’d offer a second overload which supplies a default
foperation which creates a tuple similar to what Jerry’s code does. It would even be thinkable to abstract this further to allow more than two ranges – after all, the Python list comprehension allows you to iterate over more than two ranges).