5

假设我想找到一个矩阵的大小,但不能使用任何函数,如sizenumellength。有什么巧妙的方法可以做到这一点吗?我可以想到一些使用循环的版本,例如下面的版本,但是没有循环可以做到这一点吗?

function sz = find_size(m)
sz = [0, 0]
   for ii = m'    %' or m(1,:) (probably faster)
      sz(1) = sz(1) + 1;
   end

   for ii = m     %' or m(:,1)'
      sz(2) = sz(2) + 1;
   end    
end

并且记录在案:这不是家庭作业,这是出于好奇。尽管这个问题的解决方案在这种情况下永远不会有用,但它们有可能提供关于如何使用某些功能/技术的新知识。

4

5 回答 5

8

这是一个更通用的解决方案

function sz = find_size(m)
sz = [];
m(f(end), f(end));
    function r = f(e)
        r=[];
        sz=[sz e];
    end
end

哪个

  1. 适用于数组元胞数组对象数组
  2. 它的时间复杂度是恒定的并且与矩阵大小无关
  3. 不使用任何 MATLAB 函数
  4. 容易适应更高的维度
于 2013-10-09T22:59:03.753 回答
3

对于非空矩阵,您可以使用:

sz = [sum(m(:,1)|1) sum(m(1,:)|1)];

但是为了覆盖空矩阵,我们需要更多的函数调用

sz = sqrt([sum(sum(m*m'|1)) sum(sum(m'*m|1))]);

或更多行

n=m&0;
n(end+1,end+1)=1;
[I,J]=find(n);
sz=[I,J]-1;

两者都适用于m=zeros(0,0),m=zeros(0,10)m=zeros(10,0)

于 2013-10-09T20:40:09.210 回答
2

增量索引和 try-catch 语句有效:

function sz = find_size(m)

  sz = [0 0];

  isError = false;
  while ~isError
    try
      b = m(sz(1) + 1, :);
      sz(1) = sz(1) + 1;
    catch
      isError = true;
    end
  end

  isError = false;
  while ~isError
    try
      b = m(:, sz(2) + 1);
      sz(2) = sz(2) + 1;
    catch
      isError = true;
    end
  end

end
于 2013-10-09T19:07:22.020 回答
2

一个非常通用的解决方案是:

[ sum(~sum(m(:,[]),2)) sum(~sum(m([],:),1)) ]

它接受矩阵(0 列、0 行或两者兼有) ,以及complexNaNinf值。

它也非常快:对于 1000 × 1000 矩阵,在我的旧笔记本电脑中大约需要 22 微秒(for重复 1e5 次的循环需要 2.2 秒,用 , 测量tictoc


这是如何工作的

统一处理空矩阵的关键是:

  • 空索引(即用 索引[]);
  • 沿空维度求和的事实为零。

rc为 的行数和列数(可能为零)mm(:,[])是一个r × 0 的空向量。即使rc为零,这仍然成立。此外,这种空索引会自动提供对 或 中的复杂值的不敏感性NaNinf并且m可能还考虑了较小的计算时间)。

将r × 0 向量沿其第二维 ( )求和sum(m(:,[]),2)会产生一个r × 1 零向量。对该向量求反和求和得到r

通过在第一个维度中空索引并沿该维度求和,对列数c应用相同的过程。

于 2013-10-09T21:02:08.767 回答
1

find命令有一个简洁的选项来获取最后的K元素:

I = find(X,K,'last')最多返回最后一个K indices corresponding to the nonzero entries of the arrayX`。

要获得大小,请询问最后一个k=1元素。例如,

>> x=zeros(256,4);
>> [numRows,numCols] = find(x|x==0, 1, 'last')
numRows =
   256
numCols =
     4
>> numRows0 = size(x,1), numCols0 = size(x,2)
numRows0 =
   256
numCols0 =
     4

您可以使用find单输出参数语法,这将为您提供numel

>> numEl = find(x|x==0, 1, 'last')
numEl =
        1024
>> numEl0 = numel(x)
numEl0 =
        1024

另一个简单但不太有趣的解决方案使用whos(感谢 Navan 的提醒):

s=whos('x'); s.size

最后,有format debug.

于 2013-10-09T18:49:59.983 回答