Matlab从含数字块的行向量提取值与索引构建2×m矩阵方法
问题根因
原有实现的边界检测逻辑仅识别0→非零的上升跳变和非零→0的下降跳变,默认所有非零数字块都被0分隔,因此遇到两个数值不同的非零块直接相邻(无0间隔)时,无法识别块间分界,最终导致块漏检。同时原有逻辑需要额外判断末尾块的边界,分支冗余,执行效率低。
鲁棒高效实现方案
核心逻辑是直接识别所有连续同值块,再过滤掉值为0的块即可,完全不依赖0作为块分隔标记,天然兼容无0分隔的相邻非零块场景,全程使用Matlab内置向量化函数,无循环、无冗余边界补全分支,执行效率高。
% 统一将输入转为行向量,兼容列向量输入 A = A(:).'; vec_len = length(A); % 标记所有块起始位置:相邻值不同的位置即为新块起点 block_start_mask = [true, diff(A) ~= 0]; % 为每个连续同值块分配唯一ID block_id = cumsum(block_start_mask); % 按块聚合计算:第一行存块的数值,第二行存块平均索引向下取整的结果 block_val = splitapply(@(x)x(1), A, block_id); block_avg_idx = splitapply(@(idx)floor(mean(idx)), 1:vec_len, block_id); % 过滤值为0的块,得到最终输出 out = [block_val(block_val~=0); block_avg_idx(block_val~=0)];
效果验证
- 测试用例1(非零块均被0分隔):
输入A = [0 0 1 1 1 1 0 0 0 0 22 22 22 0 0 6 6 6 6 6 0 1 1],输出为:
与预期结果完全一致。out = 1 22 6 1 4 12 18 22 - 测试用例2(存在无0分隔的相邻非零块):
输入A = [0 0 1 1 1 1 0 0 0 0 22 22 22 0 0 6 6 6 6 6 1 1],输出为:
与预期结果完全一致,不会漏检末尾无0分隔的1值块。out = 1 22 6 1 4 12 18 21
方案优势
- 鲁棒性强:不依赖0作为块分隔标记,只要相邻位置数值发生变化就会切分块,覆盖所有连续同值块场景
- 效率更高:全程向量化运算,无显式循环,针对超长向量的处理速度远优于多轮
find+分支判断的写法 - 代码简洁:无需手动补全向量末尾的块边界,逻辑清晰易维护
内容的提问来源于stack exchange,提问作者BillBokeey
相关产品推荐
相关产品推荐

