Perl数组序列校验问题:排查缺失的主编号与子编号
Perl数组序列完整性校验问题
我有如下Perl数组:
my @tests = qw(1-1 1-2 1-3 1-5 2-1 2-2 2-4 3-1 3-2 4-1 4-2 6-1 6-2);
需要校验主编号(如1)和子编号(如1-1中连字符后部分)的序列完整性,预期输出为:Missing numbers 1-4, 2-3, 5。
以下是我的代码,请问哪里存在问题?
my @tests = qw(1-1 1-2 1-3 1-5 2-1 2-2 2-4 3-1 3-2 4-1 4-2 6-1 6-2); my %sub_numbers; foreach my $test (@tests) { $sub_numbers{$test} = 1; # Mark sub-number as present } my ($min, $max) = get_min_max_sub_numbers(\@tests); my @missing_sub_numbers; for my $i ($min..$max) { for my $j (1..5) { my $sub_number = "$i-$j"; unless ($sub_numbers{$sub_number}) { push @missing_sub_numbers, $sub_number; } } } my @filtered_missing_sub_numbers; foreach my $missing_sub_number (@missing_sub_numbers) { my ($number) = split('-', $missing_sub_number); my $previous_sub_number = ($number - 1) . "-" . substr($missing_sub_number, 2); my $next_sub_number = ($number + 1) . "-" . substr($missing_sub_number, 2); unless ($sub_numbers{$previous_sub_number} || $sub_numbers{$next_sub_number}) { push @filtered_missing_sub_numbers, $missing_sub_number; } } if (@filtered_missing_sub_numbers) { print "Missing sub-numbers: " . join(", ", @filtered_missing_sub_numbers) . "\n"; } else { print "No missing sub-numbers found.\n"; } sub get_min_max_sub_numbers { my ($tests_ref) = @_; my ($min, $max) = (undef, undef); foreach my $test (@$tests_ref) { my ($num) = split('-', $test); $min = $num if !defined($min) || $num < $min; $max = $num if !defined($max) || $num > $max; } return ($min, $max); }
代码存在的问题
- 错误固定子编号范围:代码里硬遍历子编号1到5,但实际数据中部分主编号(如3、4)的子编号只到2,会生成大量无关的缺失项(比如3-3、4-5),后续过滤逻辑也无法正确筛选出真正需要的缺失项。
- 过滤逻辑完全偏离需求:当前过滤逻辑检查的是缺失项的「跨主编号同子编号」是否存在,这和实际需求(检查主编号下子项连续性、主编号本身连续性)完全不匹配。
- 未检测完全缺失的主编号:原代码根本没考虑主编号序列的连续性,比如主编号5完全不存在,无法被识别出来。
- 输出文本不符合预期:原代码输出的是
Missing sub-numbers:,但需求是Missing numbers。
修正后的代码
my @tests = qw(1-1 1-2 1-3 1-5 2-1 2-2 2-4 3-1 3-2 4-1 4-2 6-1 6-2); # 按主编号分组存储子编号,方便后续检查 my %main_sub_map; foreach my $test (@tests) { my ($main, $sub) = split('-', $test); $main_sub_map{$main}{$sub} = 1; } # 获取排序后的主编号列表,以及最小、最大主编号 my @sorted_mains = sort { $a <=> $b } keys %main_sub_map; my ($min_main, $max_main) = ($sorted_mains[0], $sorted_mains[-1]); my @missing; # 检查每个主编号下的子编号连续性 foreach my $main (@sorted_mains) { my @sorted_subs = sort { $a <=> $b } keys %{$main_sub_map{$main}}; my $prev_sub = 0; foreach my $sub (@sorted_subs) { # 找出相邻子编号之间的缺失项 if ($sub - $prev_sub > 1) { push @missing, "$main-$_" for ($prev_sub + 1 .. $sub - 1); } $prev_sub = $sub; } } # 检查主编号序列的连续性,找出完全缺失的主编号 for my $main ($min_main .. $max_main) { push @missing, $main unless exists $main_sub_map{$main}; } # 输出结果 if (@missing) { print "Missing numbers " . join(", ", @missing) . "\n"; } else { print "No missing numbers found.\n"; }
修正说明
- 数据结构优化:用哈希表分组存储主-子编号关系,避免原代码把所有项扁平化存储的混乱。
- 子编号连续性检查:对每个主编号下的子编号排序后,遍历找出相邻子项之间的缺失值。
- 主编号连续性检查:遍历最小到最大主编号的所有值,直接找出完全不存在的主编号。
- 输出匹配需求:调整输出文本为
Missing numbers,结果完全符合预期。
内容的提问来源于stack exchange,提问作者ssr1012
相关产品推荐
相关产品推荐

