You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效识别含1、0、-1的数组中连续1集合的起止索引?

性能优化方案

你现有代码耗时高主要有两个核心原因:

  1. 嵌套逐元素遍历的while循环,Matlab的M语言循环本身执行效率远低于内置优化函数
  2. 未预分配startt、endd数组,动态扩容会频繁触发内存重新分配,额外增加大量开销
    另外你现有代码里的index变量看起来是笔误,按逻辑应该是1。

最优向量化实现(推荐)

利用你数据的规则:-1固定是连续1块的结束标记,完全可以用内置向量化函数实现,性能比手写循环高10~100倍,代码也更简洁:

% 处理数组起始位是1的边界情况,补一个前置0
padded_slots = [0, link_slots];
% 找所有连续1块的起始位置:当前位是1,前一位不是1
start_idx = find(padded_slots(1:end-1) ~= 1 & padded_slots(2:end) == 1);
% 找所有-1的位置,减1就是对应连续1块的结束位置
end_idx = find(link_slots == -1) - 1;

拿你给的示例验证:
输入样例[1 1 1 -1 0 0 0 0 1 1 -1 0 0 1 1 1 1 -1 0 0]

  • 找到的-1位置是4、11、18,减1后得到end_idx = [3,10,17]
  • 找到的起始位置是1、9、14,和你预期的结果完全一致。

优化后的循环版本(如果需要保留循环逻辑)

如果业务场景需要保留循环写法,可按下面的方式优化,性能也比原有代码提升数倍:

n = numel(link_slots);
% 预分配足够大的结果数组,避免动态扩容
max_block_num = floor(n/2); % 最坏情况每两个元素一个块(1 + -1)
startt = zeros(1, max_block_num);
endd = zeros(1, max_block_num);
block_count = 0;

i = 1;
while i <= n
    if link_slots(i) == 1
        block_count = block_count + 1;
        startt(block_count) = i;
        % 直接找当前位置后第一个-1,不用逐次累加j
        next_neg1 = find(link_slots(i:end) == -1, 1, 'first');
        endd(block_count) = i + next_neg1 - 2;
        % 直接跳转到-1之后的位置,减少无效遍历
        i = i + next_neg1;
    else
        i = i + 1;
    end
end
% 截断预分配的多余空间
startt = startt(1:block_count);
endd = endd(1:block_count);

对于长度为800的数组,上述两种方案的单次执行耗时都在微秒级,批量处理数千个数组也不会有性能问题。

内容的提问来源于stack exchange,提问作者knowledge_seeker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:24:02