gpt4 book ai didi

perl - 当月的日期跨越当月末到下月初时,如何重新排列月的日期

转载 作者:行者123 更新时间:2023-12-04 16:36:44 24 4
gpt4 key购买 nike

我必须处理根据月份日期变化的数据。当我从文件名中提取日期时,我得到了一个随机排列的日期,如下所示。

31 02 28 30 27 01 29 03 04

这是在处理从 8 月 27 日到 9 月 4 日的数据。我需要从 27 日到 4 日按顺序排列的日期。我必须一次处理 9 个日期。这个问题出现在月底,当时我有这个月的日期(大数字)和下个月的日期(小数字)。所以我对数组进行排序,我称之为@fdaylist。我明白了

01 02 03 04 27 28 29 30 31.

为了得到我想要的下面的脚本片段,完成工作并给出

27 28 29 30 31 01 02 03 04

我确定这个脚本是否可以一直运行。它多次重现序列,所以我必须使用 uniq() 函数。如果我能得到有关实现目标的更好方法的建议,我将不胜感激。

my $last_occ=lastidx { /0\d/ } @fdaylist;
if($last_occ > 1){
foreach(@fdaylist){
for(my $mm=$last_occ+1; $mm < @fdaylist; ++$mm){
push (@fday, $fdaylist[$mm]);
}
for(my $nn=0; $nn <= $last_occ; ++$nn){
push (@fday, $fdaylist[$nn]);
}
}
}
@fday = uniq(@fday);

最佳答案

我假设数字必须是连续的,有一个间隔,否则无法确定某些人属于哪一种方式。我还假设总是存在间隙。(不。虽然日期确实是连续的,但它们可能跨越两个月在一个月内,正如所澄清的那样。)

一种方法:遍历排序数组,从前到后移动项目,直到到达间隙

use warnings;
use strict;
use feature 'say';

# Dates are consecutive, either straddling two months or within a month
my @dates = (31, 02, 28, 30, 27, 01, 29, 03, 04); # or can be 05..13 etc

@dates = sort { $a <=> $b } @dates;

if (consec_nums(\@dates)) {
say "Consecutive numbers (dates in same month), nothing to do (@dates)";
}
else {
my $last_moved;
while (1) {
push @dates, $last_moved = shift @dates;
last if $dates[0] > $last_moved+1;
}

@dates = map { sprintf "%02d", $_ } @dates; # for 01 02 etc
}
say "@dates";

# Returns true (1) if numbers are consecutive, like consecutive dates
# in a single month, false (undef) otherwise. Assumes a sorted array
sub consec_nums {
my ($ra) = @_;
my $prev = $ra->[0];
for my $i (1..$#$ra) {
return if $ra->[$i] > $prev+1;
$prev = $ra->[$i];
}
return 1;
}

另一种方法:遍历已排序的数组以找到间隙之前的最后一个索引(之后数字不再连续);然后拼接推送

# same sorted @dates, same assumptions. same consec_nums() sub

if (consec_nums(\@dates)) {
say "Consecutive numbers (dates in same month), nothing to do (@dates)";
}
else {
my $consec_idx;
for my $i (0 .. $#dates) {
$consec_idx = $i, last
if $dates[$i]+1 < $dates[$i+1];
}

push @dates, splice @dates, 0, $consec_idx+1;
}

say "@dates";

对于上述假设:

  • 如果我们可以得到 1 2 10 30 31 那么应该是 10 30 31 1 2 还是 30 31 1 2 10?

  • 如果没有间隙(一个月内的所有日期),如 05 .. 13,则上述过程将中断。如果可能出现这种情况,那么首先对其进行测试。

    已经在评论中澄清了这确实是可能的,所有日期都在一个月内。上面的答案已经通过针对这种情况的测试进行了修改。

关于perl - 当月的日期跨越当月末到下月初时,如何重新排列月的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68959716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com