1
- use std:: cmp:: Ordering :: { Greater , Less } ;
2
1
use std:: collections:: VecDeque ;
3
2
4
3
/// 幅 `window_width` の区間すべてに対し最小値を求めます。
@@ -27,55 +26,53 @@ use std::collections::VecDeque;
27
26
/// assert_eq!(
28
27
/// minimums,
29
28
/// vec![
30
- /// 4, // 4 7 7 8 5 7
31
- /// 5, // 7 7 8 5 7 6
32
- /// 5, // 7 8 5 7 6 9
33
- /// 5, // 8 5 7 6 9 9
34
- /// 2, // 5 7 6 9 9 2
35
- /// 2, // 7 6 9 9 2 8
36
- /// 2, // 6 9 9 2 8 3
29
+ /// & 4, // 4 7 7 8 5 7
30
+ /// & 5, // 7 7 8 5 7 6
31
+ /// & 5, // 7 8 5 7 6 9
32
+ /// & 5, // 8 5 7 6 9 9
33
+ /// & 2, // 5 7 6 9 9 2
34
+ /// & 2, // 7 6 9 9 2 8
35
+ /// & 2, // 6 9 9 2 8 3
37
36
/// ]
38
37
/// );
39
38
/// ```
40
- pub fn sliding_window_minimum < T > ( a : & [ T ] , window_width : usize ) -> Vec < T >
39
+ pub fn sliding_window_minimum < T > ( a : & [ T ] , window_width : usize ) -> Vec < & T >
41
40
where
42
- T : Ord + Clone ,
41
+ T : Ord ,
43
42
{
44
- sliding_window ( a, window_width, true )
43
+ sliding_window ( a, window_width, |last , new| last >= new )
45
44
}
46
45
47
46
/// [`sliding_window_minimum`](fn.sliding_window_minimum.html) の最大値バージョンです。
48
- pub fn sliding_window_maximum < T > ( a : & [ T ] , window_width : usize ) -> Vec < T >
47
+ pub fn sliding_window_maximum < T > ( a : & [ T ] , window_width : usize ) -> Vec < & T >
49
48
where
50
- T : Ord + Clone ,
49
+ T : Ord ,
51
50
{
52
- sliding_window ( a, window_width, false )
51
+ sliding_window ( a, window_width, |last , new| last <= new )
53
52
}
54
53
55
- fn sliding_window < T > ( a : & [ T ] , window_width : usize , choose_minimum : bool ) -> Vec < T >
54
+ fn sliding_window < T , F > ( a : & [ T ] , window_width : usize , pop_back_cond : F ) -> Vec < & T >
56
55
where
57
- T : Ord + Clone ,
56
+ T : Ord ,
57
+ F : Fn ( & T , & T ) -> bool , // (last, new)
58
58
{
59
59
assert ! ( 0 < window_width && window_width <= a. len( ) ) ;
60
60
let mut result = Vec :: new ( ) ;
61
- let mut arg_min_max_candidates : VecDeque < usize > = VecDeque :: new ( ) ;
61
+ let mut positions : VecDeque < usize > = VecDeque :: new ( ) ;
62
62
for ( i, v) in a. iter ( ) . enumerate ( ) {
63
- while !arg_min_max_candidates. is_empty ( ) {
64
- let back = arg_min_max_candidates. back ( ) . unwrap ( ) ;
65
- if choose_minimum && a[ * back] . cmp ( v) == Less {
63
+ while let Some ( last) = positions. back ( ) . copied ( ) {
64
+ if pop_back_cond ( & a[ last] , v) {
65
+ positions. pop_back ( ) ;
66
+ } else {
66
67
break ;
67
68
}
68
- if !choose_minimum && a[ * back] . cmp ( v) == Greater {
69
- break ;
70
- }
71
- arg_min_max_candidates. pop_back ( ) ;
72
69
}
73
- arg_min_max_candidates . push_back ( i) ;
70
+ positions . push_back ( i) ;
74
71
if i >= window_width - 1 {
75
- let arg_min_max = arg_min_max_candidates . front ( ) . unwrap ( ) ;
76
- result. push ( Clone :: clone ( & a[ * arg_min_max ] ) ) ;
77
- if * arg_min_max == i - ( window_width - 1 ) {
78
- arg_min_max_candidates . pop_front ( ) ;
72
+ let p = positions . front ( ) . copied ( ) . unwrap ( ) ;
73
+ result. push ( & a[ p ] ) ;
74
+ if p == i - ( window_width - 1 ) {
75
+ positions . pop_front ( ) ;
79
76
}
80
77
}
81
78
}
@@ -92,23 +89,23 @@ mod tests {
92
89
assert_eq ! (
93
90
sliding_window_minimum( & a, 4 ) ,
94
91
vec![
95
- 2 , // 2 2 3 6
96
- 0 , // 2 3 6 0
97
- 0 , // 3 6 0 6
98
- 0 , // 6 0 6 7
99
- 0 , // 0 6 7 9
100
- 6 , // 6 7 9 7
101
- 7 , // 7 9 7 7
102
- 4 , // 9 7 7 4
103
- 4 // 7 7 4 9
92
+ & 2 , // 2 2 3 6
93
+ & 0 , // 2 3 6 0
94
+ & 0 , // 3 6 0 6
95
+ & 0 , // 6 0 6 7
96
+ & 0 , // 0 6 7 9
97
+ & 6 , // 6 7 9 7
98
+ & 7 , // 7 9 7 7
99
+ & 4 , // 9 7 7 4
100
+ & 4 , // 7 7 4 9
104
101
]
105
102
) ;
106
103
107
- assert_eq ! ( sliding_window_minimum( & a, 1 ) , a) ;
104
+ assert_eq ! ( sliding_window_minimum( & a, 1 ) , a. iter ( ) . collect :: < Vec <_>> ( ) ) ;
108
105
109
106
assert_eq ! (
110
107
sliding_window_minimum( & a, a. len( ) ) ,
111
- vec![ a. iter( ) . copied ( ) . min( ) . unwrap( ) ] ,
108
+ vec![ a. iter( ) . min( ) . unwrap( ) ] ,
112
109
) ;
113
110
}
114
111
@@ -118,35 +115,35 @@ mod tests {
118
115
assert_eq ! (
119
116
sliding_window_maximum( & a, 4 ) ,
120
117
vec![
121
- 6 , // 2 2 3 6
122
- 6 , // 2 3 6 0
123
- 6 , // 3 6 0 6
124
- 7 , // 6 0 6 7
125
- 9 , // 0 6 7 9
126
- 9 , // 6 7 9 7
127
- 9 , // 7 9 7 7
128
- 9 , // 9 7 7 4
129
- 9 // 7 7 4 9
118
+ & 6 , // 2 2 3 6
119
+ & 6 , // 2 3 6 0
120
+ & 6 , // 3 6 0 6
121
+ & 7 , // 6 0 6 7
122
+ & 9 , // 0 6 7 9
123
+ & 9 , // 6 7 9 7
124
+ & 9 , // 7 9 7 7
125
+ & 9 , // 9 7 7 4
126
+ & 9 , // 7 7 4 9
130
127
]
131
128
) ;
132
129
133
- assert_eq ! ( sliding_window_maximum( & a, 1 ) , a) ;
130
+ assert_eq ! ( sliding_window_maximum( & a, 1 ) , a. iter ( ) . collect :: < Vec <_>> ( ) ) ;
134
131
135
132
assert_eq ! (
136
133
sliding_window_maximum( & a, a. len( ) ) ,
137
- vec![ a. iter( ) . copied ( ) . max( ) . unwrap( ) ] ,
134
+ vec![ a. iter( ) . max( ) . unwrap( ) ] ,
138
135
) ;
139
136
}
140
137
141
138
#[ test]
142
139
#[ should_panic]
143
140
fn test_empty_0 ( ) {
144
- assert_eq ! ( sliding_window_minimum:: <u32 >( & [ ] , 0 ) , vec! [ ] ) ;
141
+ assert ! ( sliding_window_minimum:: <u32 >( & [ ] , 0 ) . is_empty ( ) ) ;
145
142
}
146
143
147
144
#[ test]
148
145
#[ should_panic]
149
146
fn test_empty_1 ( ) {
150
- assert_eq ! ( sliding_window_minimum:: <u32 >( & [ ] , 1 ) , vec! [ ] ) ;
147
+ assert ! ( sliding_window_minimum:: <u32 >( & [ ] , 1 ) . is_empty ( ) ) ;
151
148
}
152
149
}
0 commit comments