2

我想创建一个矩阵

A = [0 0 0 0 1;
     0 0 0 1 1;
     0 0 0 1 1;
     0 0 0 1 1;
     0 0 1 1 1;
     0 1 1 1 1]

基于一个向量,该向量指示每行上应该有多少个“0”在“1”之前:

B = [4 3 3 3 2 1]

有没有一种无循环的方式来做到这一点?

4

3 回答 3

3

你没有在你的问题中提到应该如何定义数组的水平大小(个数)。

对于预定义的宽度,您可以使用以下代码:

width = 5;

A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,width-x) ], B, 'UniformOutput', false)');

如果您希望 A 具有最小宽度,但每行仍然至少有一个 1:

A = cell2mat(arrayfun(@(x) [ zeros(1,x), ones(1,max(B)+1-x) ], B, 'UniformOutput', false)');
于 2012-04-21T12:01:10.010 回答
2

在没有循环的情况下实现这一点的更短的“老派”方法如下:

A = repmat(B',1,max(B)+1)<repmat([1:max(B)+1],size(B,2),1)

如果你想拥有最少数量的

min_ones=1; %or whatever
A = repmat(B',1,max(B)+min_ones)<repmat([1:max(B)+min_ones],size(B,2),1)

我不知道这与 @nrz 的方法相比如何快速比较(我现在只有 Octave),但对我来说它更直观,因为它只是比较max(B) + min_onesB 的 * 列平铺:

4  4  4  4  4
3  3  3  3  3
3  3  3  3  3
3  3  3  3  3
2  2  2  2  2
1  1  1  1  1

行平铺 [1 : max(B) + min_ones]

1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5

生成:

A =

  0  0  0  0  1
  0  0  0  1  1
  0  0  0  1  1
  0  0  0  1  1
  0  0  1  1  1
  0  1  1  1  1
于 2012-04-21T17:41:44.767 回答
2

这只需要一行,并且似乎比以前基于repmator的解决方案更快arrayfun

%// Example data
ncols = 5;
B = [4 3 3 3 2 1];

%// Generate A
A = bsxfun(@gt, 1:ncols, B(:));
于 2013-12-16T23:02:26.473 回答