我必須處理按月份日期排列的資料。當我從檔案名中提取日期時,我得到了一個隨機排列的日期,如下所示。
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 { /0d/ } @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)/span>。
uj5u.com熱心網友回復:
我認為這些數字必須是連續的,有一個間隙,否則就不可能決定一些數字屬于哪種方式。我還假設總是有一個缺口。?(不。雖然日期確實是連續的,但它們可能跨越兩個月或位于一個月內,正如所澄清的。)
一種方法。通過排序后的陣列,將專案從前面移到后面,直到達到一個缺口為止
一種方法:將專案從前面移到后面。
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)。) # 或者可以是05. .13等
@dates = sort { $a <=> $b } @dates;
if (consec_nums(@dates)) {
say "連續的數字(同月的日期),沒什么可做的(@dates)"。
}
else {
my $last_moved;
while (1) {
push @dates, $last_moved = shift @dates;
last if $dates[0] > $last_moved 1;
}
@dates = map { sprintf "d"/span>, $_ } @dates; # 為01 02等。
}
say "@dates"/span>;
# 如果數字是連續的,則回傳真(1),如連續的日期。
# 在單個月份中,否則為假(undef)。 假設是一個排序的陣列。
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;
}
另一種方法。翻閱排序后的陣列,找到間隙前的最后一個索引(在這之后數字就不再是連續的了);然后進行拼接和推送
# 相同的排序@dates,相同的假設。相同的consec_nums() sub
if (consec_nums(@dates)) {
say "連續的數字(日期在同一個月),沒有什么可以做(@dates)"。
}
else {
my $consec_idx;
for my $i (0 ... $#dates) {
$consec_idx = $i, last last
if $dates[$i] 1 < $dates[$i 1] 。
}
push @dates, splice @dates, 0, $consec_idx 1;
}
say "@dates"/span>;
?對于提到的假設:
如果我們可以有
1 2 10 30 31,那么應該是10 30 31 1 2或30 31 1 2 10?如果沒有間隙(所有的日期都在一個月內),比如
05 ... 13,那么上面的程式就會中斷。如果這種情況是可能的,那么首先要進行測驗。有人在評論中澄清,這確實是可能的,所有的日期都在一個月內。 上面的答案已經被修正為對這種情況的測驗。
uj5u.com熱心網友回復:
請看看下面的示例代碼是否執行了你帖子中描述的操作。
該代碼:
- 將日期讀成一個字串 。
- 拆分字串并將日期排序到一個陣列中 。
- 找到最后一天的索引,從
0d開始。
- 用兩個陣列切片重新排列陣列 。
注意:列印出來的是輸入的、有序的和重新排序的資料
。span class="hljs-keyword">use strict;
use warnings;
use feature 'say';
while( < DATA> ) {
chomp;
say 'GOT: '/span> . $_;
my @dates = sort split ' '/span>, $_;
say 'IN: ' . join(' ',@dates)。
my $index = -1;
/0d/ && $index for @dates;
@dates = (@dates[$index 1...$#dates],@dates[0...$index]) 。
say 'OUT: ' . join(', @dates);
say '-' x 45。
}
__DATA__
31 02 28 30 27 01 29 03 04
28 03 26 02 25 01 23 22 24
輸出
GOT: 31 02 28 30 27 01 29 03 04
在。 01 02 03 04 27 28 29 30 31
出局。27 28 29 30 31 01 02 03 04
---------------------------------------------
GOT。28 03 26 02 25 01 23 22 24
在。 01 02 03 22 23 24 25 26 28
出局。22 23 24 25 26 28 01 02 03
---------------------------------------------
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/311352.html
標籤:
