我有大约100,000个号码,我想根据两个或两个增量组合在一起。
PS:增量值可能会改变,主阵列“x”中的值只能使用一次。
如果从“x”数组重复“array_all”数组中的数字,我不确定如何检查和停止循环。
见下面的例子
示例:
x=[9,8,7,6,5,4,3,2,1]
我正在尝试将array_all数组看起来像这样:
array_all=
[ 9.00000 4.50000 2.25000
8.00000 4.00000 2.00000
7.00000 3.50000 1.75000
6.00000 3.00000 1.50000
5.00000 2.50000 1.25000
1.00000 0.50000 0.25000]
,动态命名的数组看起来像这样
array_dyn_name1=[9,4.5,2.25]
array_dyn_name2=[8,4,2]
array_dyn_name3=[7,3.5,1.75]
array_dyn_name4=[6,3,1.5]
array_dyn_name5=[5,2.5,1.25]
array_dyn_name6=[1,.5,.25]
PS:我不仅仅停留在数组“array_dyn_name6”的原因是因为数字不会那么简单就会有数千个。我不知道他们什么时候会重复。
事件顺序:
1.从 x 数组中的最高数字开始,将该数字和输出数除以2并将其放入另一个名为 array_all 的数组中,执行此操作3次
2.将 array_all 的每一行放入名为 array_dyn_name 的动态命名数组中
3.对 x 数组中的每个值执行此操作,除非之前已在 array_all 数组中使用过该数字
注意:您可以看到 array_all数组不是以4,3或2开头,因为它们以前在 array_all数组中使用
下面的代码有效,但是我不知道如果从“x”数组中重复“array_all”数组中的数字,如何检查和停止循环。
%test grouping
clear all, clc, tic, clf;
x=[9,8,7,6,5,4,3,2,1]
div=[1,2,4] %numbers to use as divisor
array_all=[];
for ii=1:length(x)
for jj=1:length(div)
array_all(ii,jj)=x(ii)/div(jj) %divide each number and successive number by div
end
genvarname('array_dyn_name', num2str(ii)) %create dynamic variable
eval(['array_dyn_name' num2str(ii) '= array_all(ii,:)']) %places row into dynamic variable
end
fprintf('\nfinally Done-elapsed time -%4.4fsec- or -%4.4fmins- or -%4.4fhours-\n',toc,toc/60,toc/3600);
我的输出如下:
array_all =
9.00000 4.50000 2.25000
8.00000 4.00000 2.00000
7.00000 3.50000 1.75000
6.00000 3.00000 1.50000
5.00000 2.50000 1.25000
4.00000 2.00000 1.00000
3.00000 1.50000 0.75000
2.00000 1.00000 0.50000
1.00000 0.50000 0.25000
PS:我使用八度音阶3.8.1就像matlab
答案 0 :(得分:2)
你可以尝试
array_all = bsxfun( @times, x(:), [1 .5 .25] ); %// generate for all values
现在,使用ismember
我们修剪array_all
[Lia Locb] = ismember( x(:), reshape( array_all.', [], 1 ) ); %// order elements of array_all row by row
通过构造,x
的所有元素都在array_all
中,但我们想要修剪第一个元素已经出现在前一行中的行。
firstRowToAppearIn = ceil(Locb/3);
所以
toBePruned = 1:numel(x) > firstRowToAppearIn; %// prune elements that appear in array_all in a row preceding their location in x
array_all(toBePruned,:) = []; %// remove those lines
现在我们可以根据array_dyn_name
定义array_all
-
Using eval
is HORRIBLE,而是使用structure with dynamic field names:
st = struct();
for ii=1:size(array_all,1)
nm = sprintf('array_dyn_name%d',ii);
st.(nm) = array_all(ii,:);
end
似乎ismember
的第二个输出(Locb
)可能在Matlab和octave之间以不同方式排序(可能在新版和旧版本的matlab之间)。所以,这是另一种选择,使用bsxfun:
eq_ = bsxfun( @eq, array_all, permute( x(:), [3 2 1] ) );
eq_ = max( eq_, [], 2 ); %// we do not care at which column of array_all x appeared
[mx firstRowToAppearIn] = max( squeeze(eq_), [], 1 );
PS,
除了使用eval
之外,您的实现中还有另一个空洞:您没有为array_all
预先分配空间 - 这可能会导致您的代码运行速度明显慢于实际需要的速度。有关预分配的信息,请参阅this thread。