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

Perl内置函数能否查找数组中精确顺序匹配的子数组?

Perl 有序子数组匹配方案说明

Perl 核心没有提供单步完成「有序精确子数组匹配+批量返回起始索引+移除匹配段」全套操作的专用内置函数,但依托原生数组操作能力,无需安装任何第三方模块,即可实现完全符合需求的逻辑,支持数字、字符串等任意可做相等判断的元素类型。

核心实现代码

use strict;
use warnings;

# 查找所有有序精确匹配的子数组起始索引,默认支持重叠匹配
sub find_subarray_indices {
    my ($main_arr, $sub_arr) = @_;
    my @match_indices;
    my $main_len = @$main_arr;
    my $sub_len = @$sub_arr;

    return @match_indices if $sub_len > $main_len || $sub_len == 0;

    for my $start (0 .. $main_len - $sub_len) {
        my $match_flag = 1;
        for my $offset (0 .. $sub_len - 1) {
            # 比对逻辑可按需调整:数值类型可将ne替换为!=,引用/对象可自定义相等判断规则
            if ($main_arr->[$start + $offset] ne $sub_arr->[$offset]) {
                $match_flag = 0;
                last;
            }
        }
        push @match_indices, $start if $match_flag;
    }
    return @match_indices;
}

# 从左到右非重叠移除所有匹配的子数组,返回处理后的新数组,不修改传入的原数组
sub remove_matched_subarrays {
    my ($main_arr, $sub_arr) = @_;
    my $main_len = @$main_arr;
    my $sub_len = @$sub_arr;
    return @$main_arr if $sub_len > $main_len || $sub_len == 0;

    my @keep_mark = (1) x $main_len;
    my $i = 0;
    while ($i <= $main_len - $sub_len) {
        my $match_flag = 1;
        for my $offset (0 .. $sub_len - 1) {
            if ($main_arr->[$i + $offset] ne $sub_arr->[$offset]) {
                $match_flag = 0;
                last;
            }
        }
        if ($match_flag) {
            # 匹配到就标记整段删除,跳过整段长度继续向后检索
            @keep_mark[$i .. $i + $sub_len - 1] = (0) x $sub_len;
            $i += $sub_len;
        } else {
            $i += 1;
        }
    }

    my @result;
    for my $idx (0 .. $main_len - 1) {
        push @result, $main_arr->[$idx] if $keep_mark[$idx];
    }
    return @result;
}

示例验证结果

  • 示例1:主数组(1,2,3,4,5,6,7,8,9)、子数组(2,3,4),调用find_subarray_indices返回匹配起始索引(1),符合预期。
  • 示例2:主数组(4,2,3,4,2,3,4)、子数组(2,3,4),返回匹配索引(1,4),可正常识别重复出现的匹配段。
  • 示例3:主数组(2,3,2,3,2,2,3,2)、子数组(2,3,2),调用查找函数返回索引(0,2,5),和需求要求完全一致;调用移除函数后返回剩余数组(3,2),匹配示例给出的结果。

适配说明

  • 如果查找时不需要支持重叠匹配(即匹配到一个子数组后,跳过整个匹配段长度再向后检索),只需要在查找函数匹配成功后,手动将$start累加$sub_len - 1即可。
  • 如果数组元素为引用、自定义对象等复杂类型,可替换代码中的标量比对逻辑,比如用Scalar::Util的refaddr做引用地址比对,或传入自定义相等判断回调即可。
  • 如果移除时需要删除所有匹配覆盖的位置(包括重叠区域),可调整移除逻辑为基于全量匹配索引标记删除位实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:51:25