Arrays 删除所有零值,非零值旁边的零值除外

Arrays 删除所有零值,非零值旁边的零值除外,arrays,matlab,vector,Arrays,Matlab,Vector,给定以下向量: a = [0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;0;0] 除了非零值旁边的零值之外,有人能展示或建议一种去除所有零值的方法吗 上述的预期结果是: b = [0;2;3;0;2;10;11;0;0;4;5;8;0] 如果已删除这些值: [0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;0;0] 如果不使用一组IF语句,我不确定从何处开始解决此问题,例如: for k=1:length(a) if a(k) == 0 &&

给定以下向量:

a = [0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;0;0]
除了非零值旁边的零值之外,有人能展示或建议一种去除所有零值的方法吗

上述的预期结果是:

b = [0;2;3;0;2;10;11;0;0;4;5;8;0]
如果已删除这些值:

[0;0;2;3;0;2;10;11;0;0;0;4;5;8;0;00]

如果不使用一组IF语句,我不确定从何处开始解决此问题,例如:

for k=1:length(a)
    if a(k) == 0 && a(k+1) == 0
        *delete value*
    end
    if a(k) == 0 && a(k+1) >0
        *keep/store value*
    end
    if a(k) > 0
        *keep/store value*
    end
    if a(k) == 0 && a(k-1) >0
        *keep/store value*
    end
end

等等

如果您创建了两个附加向量,一个向左移动,一个从向量
a
向右移动(编辑:使用
循环移位
,如下注释所示):

创建矩阵M:

M = [a,a_right,a_left];
并对每行进行求和:

s = sum(M,2);
然后查找与0不同的组件:

i = find(s~=0);
这将为您提供从初始向量中选择的正确索引:

b=a(i)
我得到:

b=[0;2;3;0;2;10;11;0;0;4;5;8;0]
您可以使用:

这项工作如下:

  • a
    转换为0或1的向量(
    abs(符号(a))
    ),如果
    a
    的条目为0,则转换为0,否则转换为1
  • 用三个一的掩码进行卷积(
    conv(…,一(3,1),“相同”)
    )。因此,
    a
    中的非零值在其位置和相邻位置产生非零结果
  • 将其与零进行比较,以创建一个逻辑向量,其中
    a
    被索引(
    a(…>0)
  • 这可以很容易地推广,以保持更遥远的邻居。具体地说,使用掩码
    one(2*N+1,1)
    保持小于等于
    N
    项的零值远离非零值。

    我有另一个想法(当然,与其他两个想法没有太大区别),使用逻辑索引:

    a(~(~a & ~[diff(a);0] & ~[0;diff(a)] ));
    
    说明:

    • ~
      -boolean
      not
      ,返回表示输入“相反”的布尔值
    • ~a
      -返回
      a
      的零元素(在您给出的示例中不需要它,但如果您希望保留重复的非零值,则它很重要)
    • ~[diff(a);0]&[0;diff(a)]
      -返回其对任一大小的导数为零的值
    • a(~(…)
      -返回
      a
      的值,这些值不是“两边值相同的零”,即
      b

    编写相同内容的另一种方法(使用和利用非零值的“真实性”):


    您可以将其视为查找“保留哪些值”,而不是“删除哪些值”,其中我能想到的定义哪些值要保留的最简单方法是“所有非零元素和两边都非零的零元素”.

    如果您的非零数字都不是成对的,您可以使用
    diff
    ,否则您仍然可以使用
    diff
    (只是更智能)。我刚刚意识到,如果有连续的零,你只想删除1?任何在其左侧或右侧有非零值的零值都会保留,其余的都会删除。如果有3个或更多连续的零,则至少会删除1个,例如[4,8,0,0,0,10]-输出将只是:[4,8,0,0,10]-符合上述标准的两个零将保留。@AnnaSchumann,以防您对问题的高尔菲解决方案感兴趣,。您可能需要将
    a_右
    替换为
    circshift(a,-1)
    并将
    a_左
    替换为
    circshift(a,1)
    b = a(conv(abs(sign(a)), ones(3,1), 'same')>0);
    
    a(~(~a & ~[diff(a);0] & ~[0;diff(a)] ));
    
    a( a | [diff(a);0] | [0;diff(a)] );