这个属于一般基本问题,偶尔会用到这个知识点,有些库或者软件提供了此功能函数,但按照自己思路编写是非常有意义的事了。
比如A = [1,2,3],B = [4,5],C = [6] 这里有三个矩阵,从每个矩阵取出一个元素形成组合有3*2*1=6种组合,分别为 1 4 6;
2 4 6;
3 4 6;
1 5 6;
2 5 6;
3 5 6;
下面给出2种语言的具体实现和思路。
function result = CombMatrix(T)
% 功能:COMbMATRIX, 从各个矩阵/向量中取出一个元素形成一个组合。
% 输入:T 元胞数组,里面每个cell存储一个矩阵(大小类型可不同)
% 输出:result m*n大小矩阵,其中每行为一个组合,n为T中矩阵的个数。
% author:cuixingxing
% email: cuixingxing150@gmail.com
% date: 2018-09-08
% Example: result = CombMatrix({[1,2,3],[4,5],[6]})
%
% 实现思路:按照正常思维,依次对T中每个矩阵中每个元素进行顺序递增进行组合。重要地方是
% 用到了2个关键变量:currentIdx和currentPos。分别记录当前索引值和当前矩阵位置,索引值超过
% 了矩阵大小就进行移位操作,并把之前的索引值置为1,以方便之前的矩阵元素进行组合。
%
n = length(T);
m = 1;
for i = 1:n
m = m*numel(T{i});
end
result = zeros(m,n);% 初始化
currentIdx = ones(1,n); % 初始化为1,每个数组取出一个数的索引值
currentPos = 1;% 从左到又依次对T中每个矩阵进行遍历
for i = 1:m
for j = 1:n
% 表达意思为 result(i,:) = [ele1,ele2,ele3,...];其中ele为每个矩阵中取的一个元素
result(i,j) = T{j}(currentIdx(j));
end
if currentPos>1
currentPos = currentPos -1;% 要顾及前面的元素顺序排列
end
currentIdx(currentPos) = currentIdx(currentPos)+1;
while currentIdx(currentPos)>numel(T{currentPos}) % 当前矩阵位置的元素索引不能超过矩阵大小
currentIdx(currentPos) = 1;
currentPos = currentPos+1; %进行下一个矩阵的移位操作
if currentPos >n % 循环到最后一个矩阵位置了
fprintf('Loop times:%d \n',i); % 循环次数应与m相等
break;
end
currentIdx(currentPos) = currentIdx(currentPos)+1;% 在当前矩阵位置下更新下一个元素的索引
if currentIdx(currentPos)<=numel(T{currentPos}) % 仍然在当前矩阵中的元素
break;
end
end
end
result = CombMatrix({[1,2,3],[4,5],[6]})
输出结果为:
Loop times:6
result =
1 4 6
2 4 6
3 4 6
1 5 6
2 5 6
3 5 6
C++代码为,实现思路差不多:
#include <iostream>
#include <vector>
using namespace std;
// function to print combinations that contain
// one element from each of the given arrays
void print(vector<vector<int> >& arr)
{
// number of arrays
int n = arr.size();
// to keep track of next element in each of
// the n arrays
int* indices = new int[n];
// initialize with first element's index
for (int i = 0; i < n; i++)
indices[i] = 0;
while (1) {
// print current combination
for (int i = 0; i < n; i++)
cout << arr[i][indices[i]] << " ";
cout << endl;
// find the rightmost array that has more
// elements left after the current element
// in that array
int next = n - 1;
while (next >= 0 &&
(indices[next] + 1 >= arr[next].size()))
next--;
// no such array is found so no more
// combinations left
if (next < 0)
{
delete[] indices;
return;
}
// if found move to next element in that
// array
indices[next]++;
// for all arrays to the right of this
// array current index again points to
// first element
for (int i = next + 1; i < n; i++)
indices[i] = 0;
}
}
int main() {
// initializing a vector with 3 empty vectors
vector<vector<int> > arr(3);
vector<int> vecTemp;
// now entering data
// [[1, 2, 3], [4,5], [6]]
arr[0].push_back(1);
arr[0].push_back(2);
arr[0].push_back(3);
arr[1].push_back(4);
arr[1].push_back(5);
arr[2].push_back(6);
print(arr);
return 0;
}
结果为: