我有一些这样的数据:
[3, 3, 2, None, None, None, None, None, None, 1, None, 1, None]
如果我将1 - x
分配给列表中的每个非None值,或者为每个None值分配1
,我会得到以下数字:
[-2, -2, -1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1]
如果范围中的数字总和等于1,我将索引i
中的数字分配给j
,在这种情况下,这就是分组列表的样子: / p>
[<-2, <-2, <-1, 1, 1>, 1, 1>, 1, 1>, <0, 1>, <0, 1>]
或者如果原始号码被放入:
[<3, <3, <2, None, None>, None, None>, None, None>, <1, None>, <1, None>]
每个非None值都会根据嵌套的深度给出一个分数,从0开始。例如,2
组中的<2, None, None>
得分为2.我想要创建一个计算每个数字得分的函数,返回一个数字列表,其中每个数字对应于原始列表中的下一个非None值。在上面的例子中,结果将是:
[0, 1, 2, 0, 0]
我能想到的两个解决方案:
创建每个组的开始和结束索引的列表,并为每个组查看其中包含的其他范围。
创建一个递归函数,在遇到非None值时调用自身。
其中任何一个的实现都非常有用,否则我可以使用一些技巧来创建另一个解决方案。
答案 0 :(得分:3)
不要使用递归;只需使用堆叠的正向传球。
None
。None
时,请输入循环。每次迭代,减少数组的结尾;如果它达到0则弹出它,否则退出循环。
let mut scores = Vec::new();
let mut stack = Vec::new();
for x in data {
let depth = stack.len();
if let Some(v) = x {
scores.push(depth);
stack.push(v);
} else {
while let Some(&1) = stack.last() {
stack.pop();
}
if let Some(last) = stack.last_mut() {
*last -= 1;
}
}
println!("{:?}", scores);
}
assert!(!scores.is_empty());