slice_reduce/lib.rs
1//! # 切片工具库/Slice Utilities
2//!
3//! 提供高效的切片操作函数/Provides efficient slice operations
4//!
5//! ## 功能/Features
6//! - 分块/Chunking
7//! - 搜索/Searching
8//! - 统计/Counting
9//! - 排序相关/Sorting utilities
10
11use std::{cmp::{max, min, Ordering}, collections::HashMap};
12use rand::Rng;
13
14/// 将数组分块/Chunk an array into smaller arrays
15///
16/// # 参数/Arguments
17/// * `arr` - 要分块的数组/The array to chunk
18/// * `chunk_size` - 每个块的大小/The size of each chunk
19///
20/// # 返回值/Returns
21/// 包含分块结果的 `Vec<Vec<T>>`/A vector of vectors containing the chunks
22///
23/// # 示例/Examples
24/// ```
25/// use slice_reducer::chunk;
26/// let arr = vec![1, 2, 3, 4, 5];
27/// let chunks = chunk(&arr, 2);
28/// assert_eq!(chunks, vec![vec![1, 2], vec![3, 4], vec![5]]);
29/// ```
30///
31/// # 注意/Notes
32/// - 如果 `chunk_size` 为 0,返回空向量/If `chunk_size` is 0, returns empty vector
33/// - 最后一个块可能小于 `chunk_size`/Last chunk may be smaller than `chunk_size`
34pub fn chunk<T>(arr: &[T], chunk_size: usize) -> Vec<Vec<T>>
35where
36 T: Clone,
37{
38 let mut chunks: Vec<Vec<T>> = vec![];
39 if chunk_size == 0 {
40 chunks
41 } else {
42 for i in (0..arr.len()).step_by(chunk_size) {
43 let end = min(i + chunk_size, arr.len());
44 chunks.push(arr[i..end].to_vec());
45 }
46 chunks
47 }
48}
49
50/// 按指定键函数统计元素出现次数/Count elements by key function
51///
52/// # 参数/Arguments
53/// * `items` - 要统计的数组/The array to count
54/// * `key_of` - 生成统计键的函数/Function to generate key
55///
56/// # 返回值/Returns
57/// `HashMap<K, usize>` 键为统计键,值为出现次数/Key is the grouping key, value is count
58///
59/// # 示例/Examples
60/// ```
61/// use slice_reducer::count_by;
62/// let words = ["hello", "world"];
63/// let counts = count_by(&words, |s| s.len());
64/// assert_eq!(counts[&5], 2);
65/// ```
66pub fn count_by<T, K, F>(items: &[T], key_of: F) -> HashMap<K, usize>
67where
68 K: std::hash::Hash + Eq,
69 F: Fn(&T) -> K,
70{
71 let mut result = HashMap::<K, usize>::new();
72 for item in items {
73 let key = key_of(item);
74 let count = result.entry(key).or_insert(0);
75 *count += 1;
76 }
77 result
78}
79
80/// 统计元素出现次数/Count element occurrences
81///
82/// # 参数/Arguments
83/// * `items` - 要统计的数组/The array to count
84///
85/// # 返回值/Returns
86/// `HashMap<T, usize>` 键为元素,值为出现次数/Key is element, value is count
87///
88/// # 示例/Examples
89/// ```
90/// use slice_reducer::count;
91/// let nums = [1, 2, 2, 3];
92/// let counts = count(&nums);
93/// assert_eq!(counts[&2], 2);
94/// ```
95pub fn count<T>(items: &[T]) -> HashMap<T, usize>
96where
97 T: std::hash::Hash + Eq + Clone,
98{
99 count_by(items, Clone::clone)
100}
101
102/// 反转数组/Reverse an array
103///
104/// # 参数/Arguments
105/// * `arr` - 要反转的数组/The array to reverse
106///
107/// # 返回值/Returns
108/// 反转后的新数组/New array with elements reversed
109///
110/// # 示例/Examples
111/// ```
112/// use slice_reducer::reverse;
113/// let arr = [1, 2, 3];
114/// assert_eq!(reverse(&arr), [3, 2, 1]);
115/// ```
116pub fn reverse<T>(arr: &[T]) -> Vec<T>
117where
118 T: Clone,
119{
120 let mut result = arr.to_vec();
121 result.reverse();
122 result
123}
124
125/// 线性搜索/Linear search
126///
127/// # 参数/Arguments
128/// * `arr` - 要搜索的数组/The array to search
129/// * `target` - 要查找的目标/The target to find
130///
131/// # 返回值/Returns
132/// 目标索引(如果找到)/Index of target if found
133///
134/// # 示例/Examples
135/// ```
136/// use slice_reducer::linear_search;
137/// let arr = [10, 20, 30];
138/// assert_eq!(linear_search(&arr, &20), Some(1));
139/// assert_eq!(linear_search(&arr, &40), None);
140/// ```
141pub fn linear_search<T>(arr: &[T], target: &T) -> Option<usize>
142where
143 T: PartialEq,
144{
145 for (i, item) in arr.iter().enumerate() {
146 if item == target {
147 return Some(i);
148 }
149 }
150 None
151}
152
153/// 二分查找/Binary search (要求数组已排序/Array must be sorted)
154///
155/// # 参数/Arguments
156/// * `arr` - 已排序的数组/Sorted array to search
157/// * `target` - 要查找的目标/Target to find
158///
159/// # 返回值/Returns
160/// 目标索引(如果找到)/Index of target if found
161///
162/// # 示例/Examples
163/// ```
164/// use slice_reducer::binary_search;
165/// let arr = [10, 20, 30, 40];
166/// assert_eq!(binary_search(&arr, &20), Some(1));
167/// assert_eq!(binary_search(&arr, &25), None);
168/// ```
169pub fn binary_search<T>(arr: &[T], target: &T) -> Option<usize>
170where
171 T: Ord,
172{
173 let mut left = 0;
174 let mut right = arr.len() - 1;
175 while left <= right {
176 let mid = left + (right - left) / 2;
177 match arr[mid].cmp(target) {
178 std::cmp::Ordering::Less => left = mid + 1,
179 std::cmp::Ordering::Greater => right = mid - 1,
180 std::cmp::Ordering::Equal => return Some(mid),
181 }
182 }
183 None
184}
185
186/// 滑动窗口最大值/Sliding window maximum
187///
188/// # 参数/Arguments
189/// * `slice` - 输入数组/Input array
190/// * `window_size` - 窗口大小/Window size
191///
192/// # 返回值/Returns
193/// 每个窗口的最大值组成的数组/Array of each window's maximum
194///
195/// # 示例/Examples
196/// ```
197/// use slice_reducer::sliding_window_max;
198/// let arr = [1, 3, -1, -3, 5, 3];
199/// assert_eq!(sliding_window_max(&arr, 3), vec![3, 3, 5, 5]);
200/// ```
201///
202/// # 注意/Notes
203/// - 窗口大小必须 ≤ 数组长度/Window size must ≤ array length
204pub fn sliding_window_max(slice: &[i32], window_size: usize) -> Vec<i32> {
205 let mut result = vec![];
206 for i in 0..=slice.len() - window_size {
207 let window = &slice[i..i + window_size];
208 let max = window.iter().max().unwrap();
209 result.push(*max);
210 }
211 result
212}
213
214/// 合并两个已排序数组合并保持顺序/Merge two sorted arrays
215///
216/// # 参数/Arguments
217/// * `a` - 第一个已排序数组/First sorted array
218/// * `b` - 第二个已排序数组/Second sorted array
219///
220/// # 返回值/Returns
221/// 合并后的新数组/New merged array
222///
223/// # 示例/Examples
224/// ```
225/// use slice_reducer::merge_sorted;
226/// let a = [1, 3, 5];
227/// let b = [2, 4, 6];
228/// assert_eq!(merge_sorted(&a, &b), vec![1, 2, 3, 4, 5, 6]);
229/// ```
230pub fn merge_sorted<T: Ord + Clone>(a: &[T], b: &[T]) -> Vec<T> {
231 let mut merged = vec![];
232 let mut i = 0;
233 let mut j = 0;
234 while i < a.len() && j < b.len() {
235 if a[i] <= b[j] {
236 merged.push(a[i].clone());
237 i += 1;
238 } else {
239 merged.push(b[j].clone());
240 j += 1;
241 }
242 }
243 while i < a.len() {
244 merged.push(a[i].clone());
245 i += 1;
246 }
247 while j < b.len() {
248 merged.push(b[j].clone());
249 j += 1;
250 }
251 merged
252}
253
254/// 查找字符串数组的最长公共前缀/Longest common prefix of strings
255///
256/// # 参数/Arguments
257/// * `strs` - 字符串数组/String array
258///
259/// # 返回值/Returns
260/// 最长公共前缀字符串/Longest common prefix string
261///
262/// # 示例/Examples
263/// ```
264/// use slice_reducer::longest_common_prefix;
265/// let strs = ["flower", "flow", "flight"];
266/// assert_eq!(longest_common_prefix(&strs), "fl");
267/// ```
268pub fn longest_common_prefix(strs: &[&str]) -> String {
269 if strs.is_empty() {
270 return "".to_string();
271 }
272 let mut prefix = strs[0].to_string();
273 for s in strs.iter().skip(1) {
274 while !s.starts_with(&prefix) {
275 prefix.pop();
276 if prefix.is_empty() {
277 return "".to_string();
278 }
279 }
280 }
281 prefix
282}
283
284/// 最大子数组和(Kadane算法)/Maximum subarray sum (Kadane's algorithm)
285///
286/// # 参数/Arguments
287/// * `slice` - 输入数组/Input array
288///
289/// # 返回值/Returns
290/// 最大子数组和/Maximum subarray sum
291///
292/// # 示例/Examples
293/// ```
294/// use slice_reducer::max_subarray_sum;
295/// let arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
296/// assert_eq!(max_subarray_sum(&arr), 6); // [4, -1, 2, 1]
297/// ```
298pub fn max_subarray_sum(slice: &[i32]) -> i32 {
299 let mut max_sum = slice[0];
300 let mut current_sum = slice[0];
301 for item in slice.iter().skip(1) {
302 current_sum = max(*item, current_sum + *item);
303 max_sum = max(max_sum, current_sum);
304 }
305 max_sum
306}
307
308/// 随机打乱数组/Randomly shuffle array (Fisher-Yates算法/Fisher-Yates algorithm)
309///
310/// # 参数/Arguments
311/// * `slice` - 要打乱的数组/Array to shuffle
312/// * `rng` - 随机数生成器实例/Random number generator instance
313///
314/// # 示例/Examples
315/// ```
316/// use slice_reducer::shuffle;
317/// use rand::thread_rng;
318///
319/// let mut arr = [1, 2, 3, 4, 5];
320/// let mut rng = thread_rng();
321/// shuffle(&mut arr, &mut rng);
322/// println!("{:?}", arr); // 随机顺序/Random order
323/// ```
324///
325/// # 高级用法/Advanced usage
326/// ```
327/// // 使用确定性随机源测试(需rand::rngs::mock)
328/// # #[cfg(feature = "rand")]
329/// use rand::rngs::mock::StepRng;
330/// # #[cfg(feature = "rand")]
331/// let mut test_arr = [1, 2, 3];
332/// # #[cfg(feature = "rand")]
333/// shuffle(&mut test_arr, &mut StepRng::new(0, 1));
334/// # #[cfg(feature = "rand")]
335/// assert_eq!(test_arr, [2, 1, 3]);
336/// ```
337pub fn shuffle<T, R: Rng>(slice: &mut [T], rng: &mut R) {
338 for i in (1..slice.len()).rev() {
339 let j = rng.random_range(0..=i);
340 slice.swap(i, j);
341 }
342}
343
344/// 已排序数组去重/Remove duplicates from sorted array
345///
346/// # 参数/Arguments
347/// * `slice` - 要处理的数组(必须已排序)/Array to process (must be sorted)
348///
349/// # 示例/Examples
350/// ```
351/// use slice_reducer::dedup_sorted;
352/// let mut arr = vec![1, 1, 2, 3, 3, 3];
353/// dedup_sorted(&mut arr);
354/// assert_eq!(arr, [1, 2, 3]);
355/// ```
356pub fn dedup_sorted<T>(slice: &mut Vec<T>)
357where
358 T: PartialEq + Copy,
359{
360 if slice.is_empty() {
361 return;
362 }
363
364 let mut write_index = 1;
365 for read_index in 1..slice.len() {
366 if slice[read_index] != slice[write_index - 1] {
367 slice[write_index] = slice[read_index];
368 write_index += 1;
369 }
370 }
371 slice.truncate(write_index);
372}
373
374/// 切片比较(类似字典序)/Slice comparison (lexicographical order)
375///
376/// # 参数/Arguments
377/// * `a` - 第一个切片/First slice
378/// * `b` - 第二个切片/Second slice
379///
380/// # 返回值/Returns
381/// 比较结果(Ordering)/Comparison result (Ordering)
382///
383/// # 示例/Examples
384/// ```
385/// use slice_reducer::slice_cmp;
386/// use std::cmp::Ordering;
387/// let a = [1, 2, 3];
388/// let b = [1, 2, 4];
389/// assert_eq!(slice_cmp(&a, &b), Ordering::Less);
390/// ```
391pub fn slice_cmp<T>(a: &[T], b: &[T]) -> Ordering
392where T: Ord
393{
394 let min_len = min(a.len(), b.len());
395 for i in 0..min_len {
396 match a[i].cmp(&b[i]) {
397 Ordering::Less => return Ordering::Less,
398 Ordering::Greater => return Ordering::Greater,
399 Ordering::Equal => continue,
400 }
401 }
402 a.len().cmp(&b.len())
403}
404
405/// 用模式重复填充数组/Repeat pattern to fill array
406///
407/// # 参数/Arguments
408/// * `slice` - 要填充的数组/Array to fill
409/// * `pattern` - 重复模式/Pattern to repeat
410///
411/// # 示例/Examples
412/// ```
413/// use slice_reducer::repeat_fill;
414/// let mut arr = [0; 5];
415/// repeat_fill(&mut arr, &[1, 2]);
416/// assert_eq!(arr, [1, 2, 1, 2, 1]);
417/// ```
418pub fn repeat_fill<T>(slice: &mut [T], pattern: &[T])
419where T: Copy
420{
421 if pattern.is_empty() {
422 return;
423 }
424 for i in (0..slice.len()).step_by(pattern.len()) {
425 let end = min(i + pattern.len(), slice.len());
426 slice[i..end].copy_from_slice(pattern);
427 }
428}
429
430/// 安全的分割切片/Safely split slice at index
431///
432/// # 参数/Arguments
433/// * `slice` - 要分割的切片/Slice to split
434/// * `mid` - 分割位置/Split position
435///
436/// # 返回值/Returns
437/// `Some((left, right))` 如果分割成功,否则 `None`/`Some((left, right))` if valid, else `None`
438///
439/// # 示例/Examples
440/// ```
441/// use slice_reducer::split_at_checked;
442/// let arr = [1, 2, 3, 4];
443/// assert!(split_at_checked(&arr, 2).is_some());
444/// assert!(split_at_checked(&arr, 5).is_none());
445/// ```
446pub fn split_at_checked<T> (slice: &[T], mid: usize) -> Option<(&[T], &[T])> {
447 if mid > slice.len() {
448 return None;
449 }
450 Some(slice.split_at(mid))
451}