假设我们在 MATLAB 中运行一个无限循环,并且我们希望将迭代值存储在一个向量中。我们如何在不知道向量大小的情况下声明向量?
z=??
for i=1:inf
z(i,1)=i;
if(condition)%%condition is met then break out of the loop
break;
end;
end;
假设我们在 MATLAB 中运行一个无限循环,并且我们希望将迭代值存储在一个向量中。我们如何在不知道向量大小的情况下声明向量?
z=??
for i=1:inf
z(i,1)=i;
if(condition)%%condition is met then break out of the loop
break;
end;
end;
请首先注意这是不好的做法,您应该尽可能预先分配。
话虽如此,使用end
关键字是通过单个元素扩展数组的最佳选择:
z = [];
for ii = 1:x
z(end+1, 1) = ii; % Index to the (end+1)th position, extending the array
end
您还可以连接先前迭代的结果,这往往会更慢,因为您在等号运算符的两侧都有赋值变量
z = [];
for ii = 1:x
z = [z; ii];
end
萨达尔评论说,直接索引越界(正如其他答案所暗示的那样)被 MathWorks 贬值了,我不确定这个来源。
如果您的condition
计算与输出计算分开,您可以先获得所需的大小
k = 0;
while ~condition
condition = true; % evaluate the condition here
k = k + 1;
end
z = zeros( k, 1 ); % now we can pre-allocate
for ii = 1:k
z(ii) = ii; % assign values
end
根据您的用例,您可能不知道实际的迭代次数以及向量元素,但您可能知道最大可能的迭代次数。如前所述,在每次循环迭代中调整向量的大小可能是一个真正的性能瓶颈,您可能会考虑这样的事情:
maxNumIterations = 12345;
myVector = zeros(maxNumIterations, 1);
for n = 1:maxNumIterations
myVector(n) = someFunctionReturningTheDesiredValue(n);
if(condition)
vecLength = n;
break;
end
end
% Resize the vector to the length that has actually been filled
myVector = myVector(1:vecLength);
顺便说一句,我建议你不要习惯在 Matlab 程序中使用 i 作为索引,因为这会掩盖虚数单位 i。通过这样做,我在循环内的复杂计算中遇到了一些令人讨厌的错误,所以我建议将 n 或您选择的任何其他字母作为您的首选循环索引变量名称,即使您不处理复杂的值职能 ;)
你可以声明一个空矩阵
z = []
这将创建一个 0x0 矩阵,当您向其写入数据时该矩阵将调整大小。在您的情况下,它将增长到向量 ix1。
请记住,这比使用 zeros(dim,dim) 函数预先初始化向量要慢得多。因此,如果有任何方法可以计算出 i 的最大值,您应该将其初始化为z = zeros(i,1)
干杯,西蒙
您可以将 z 初始化为一个空数组,它会在循环过程中自动扩展......类似于:
z = [];
for i = 1:Inf
z(i) = i;
if (condition)
break;
end
end
然而,这看起来很讨厌(并引发警告:警告:FOR 循环索引太大。截断为 9223372036854775807),我会在这里做一段时间(真)或条件本身并手动递增。
z = [];
i = 0;
while !condition
i=i+1;
z[i]=i;
end
和/或如果您的示例最终确实是您所需要的,请将数组的重新创建替换为:
while !condition
i=i+1;
end
z = 1:i;
正如在该线程中多次提到的,调整数组的大小是非常密集的处理,并且可能需要很多时间。
如果处理时间不是问题:
然后像@Wolfie提到的那样就足够了。在每次迭代中,数组长度都会增加,即:
z = [];
for ii = 1:x
%z = [z; ii];
z(end+1) = ii % Best way
end
如果处理时间是一个问题:
如果处理时间是一个很大的因素,并且您希望它尽可能顺利地运行,那么您需要进行预分配。如果您对将运行的最大迭代次数有一个粗略的了解,那么您可以使用@PluginPenguin 的建议。但是仍然可能会改变达到预设限制,这将破坏(或严重减慢)程序。
我的建议:
如果您的循环无限运行直到您停止它,您可以偶尔调整大小。本质上是随心所欲地扩大尺寸,但只是偶尔做一次。例如每 100 个循环:
z = zeros(100,1);
for i=1:inf
z(i,1)=i;
fprintf("%d,\t%d\n",i,length(z)); % See it working
if i+1 >= length(z) %The array as run out of space
%z = [z; zeros(100,1)]; % Extend this array (note the semi-colon)
z((length(z)+100),1) = 0; % Seems twice as fast as the commented method
end
if(condition)%%condition is met then break out of the loop
break;
end;
end
这意味着循环可以永远运行,数组会随之增加,但只是每隔一段时间。这意味着处理时间的影响将是最小的。
编辑:
正如@Cris 提到的,MATLAB 已经完成了我在内部提出的建议。这使我的两个评论完全错误。所以最好遵循@Wolfie 和@Cris 所说的话:
z(end+1) = i
希望这可以帮助!