从n个矩阵中各挑选一个元素形成组合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cuixing001/article/details/82531320

这个属于一般基本问题,偶尔会用到这个知识点,有些库或者软件提供了此功能函数,但按照自己思路编写是非常有意义的事了。

比如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: [email protected]
% 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;
}

结果为:

猜你喜欢

转载自blog.csdn.net/cuixing001/article/details/82531320