Sum of Unique Elements
关于 1748 题 Sum of Unique Elements 的 Rust 的解法。打了一个月 DNF 增幅失败脱坑,可以回归正常(误,还是打游戏爽)的生活节奏。
Description
You are given an integer array nums
. The unique elements of an array are the elements that appear exactly once in the array.
Return the sum of all the unique elements of nums
.
Example 1:
Input: nums = [1,2,3,2]
Output: 4
Explanation: The unique elements are [1,3], and the sum is 4.
Example 2:
Input: nums = [1,1,1,1,1]
Output: 0
Explanation: There are no unique elements, and the sum is 0.
Example 3:
Input: nums = [1,2,3,4,5]
Output: 15
Explanation: The unique elements are [1,2,3,4,5], and the sum is 15.
Solutions
Rust 实现:
1pub fn sum_of_unique(nums: Vec<i32>) -> i32 {
2 nums.into_iter()
3 .fold(HashMap::new(), |mut acc, v| {
4 *acc.entry(v).or_insert(0) += 1;
5 acc
6 })
7 .into_iter()
8 .filter_map(|(k, v)| if v == 1 { Some(k) } else { None })
9 .sum::<i32>()
10}
TypeScript 实现:
1function sumUnique(nums: number[]): number {
2 const counts = nums.reduce((acc: Map<number, number>, v: number) => {
3 acc.set(v, (acc.get(v) || 0) + 1);
4 return acc;
5 }, new Map<number, number>());
6
7 return Array.from(counts)
8 .filter(([_, v]) => v === 1)
9 .reduce((acc: number, [k, _]: [number, number]) => acc + k, 0);
10}
fold 和 acc 的名词解释
fold
函数在 Rust 中的功能与 reduce
在许多其他编程语言(如 JavaScript、Python 等)中的功能是相同的。fold
是一个将所有元素通过某种方式组合在一起的函数,通常用于从一个集合中生成一个单一的值。
在这个特定的代码示例中,fold
用于创建一个 HashMap
,其中的每个键值对是 nums
中的元素及其出现的次数。
acc
通常是 "accumulator" 的缩写,指的是在 fold
、reduce
或类似的函数中用于累积结果的变量。在这个情况下,acc
是一个 HashMap
,用于在迭代过程中存储每个元素及其出现次数。
accumulator 的解释
"Accumulator"在计算机科学和编程中通常用来表示一个在循环或迭代过程中累积(或收集)值的变量。在某些上下文中,它也可以被称为"reducer"或"aggregator"。
例如,在循环中,你可能有一个变量,你在每次循环迭代时都会增加它的值,这个变量就可以被看作是一个累加器。同样,你可能有一个列表或数组,你在每次迭代中都会向其中添加新的元素,这个列表或数组也可以被看作是一个累加器。
在你提供的那段Rust代码中,acc
就是一个累加器,表示的是一个正在被构建的 HashMap
。在每次迭代中,都会向这个 HashMap
中添加一个新的键值对,或者更新一个已存在的键值对的值。
filter_map 和 filter
filter_map
和 filter
都是 Rust 中的迭代器方法,用于过滤集合中的元素。它们的主要区别在于,filter_map
允许在过滤元素的同时对元素进行一些变换,而 filter
只进行过滤操作。
具体来说:
filter
方法接受一个闭包,这个闭包接受一个元素作为参数,并返回一个布尔值。如果闭包返回true
,那么该元素就会被包含在最终的结果中;如果返回false
,那么元素将被排除出结果。filter_map
方法也接受一个闭包,但这个闭包返回的是一个Option
。如果闭包返回Some(value)
,那么value
就会被包含在最终的结果中;如果返回None
,那么元素将被排除出结果。在处理元素并返回Some(value)
时,可以对元素进行一些变换。
所以说,filter_map
在 filter
的基础上提供了更大的灵活性,因为你可以在过滤元素的同时对元素进行变换。然而,如果你只需要过滤元素,而不需要进行任何变换,那么使用 filter
就足够了。
原始的 Rust 代码:
1nums.into_iter()
2 .fold(HashMap::new(), |mut acc, v| {
3 *acc.entry(v).or_insert(0) += 1;
4 acc
5 })
6 .into_iter()
7 .filter_map(|(k, v)| if v == 1 { Some(k) } else { None })
8 .sum::<i32>()
用 filter
替换 filter_map
后的代码:
1nums.into_iter()
2 .fold(HashMap::new(), |mut acc, v| {
3 *acc.entry(v).or_insert(0) += 1;
4 acc
5 })
6 .into_iter()
7 .filter(|&(_, v)| v == 1)
8 .map(|(k, _)| k)
9 .sum::<i32>()
在新代码中,我先使用 filter
过滤出只出现一次的元素,然后用 map
提取出这些元素的值(k
),最后将这些值相加。