如果范围中的数字总和等于1

时间:2016-02-18 08:39:45

标签: function recursion rust

我有一些这样的数据:

[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值时调用自身。

其中任何一个的实现都非常有用,否则我可以使用一些技巧来创建另一个解决方案。

1 个答案:

答案 0 :(得分:3)

不要使用递归;只需使用堆叠的正向传球。

  • 保留一堆“开放式”括号以及预计会有多少None
  • 当您看到None时,请输入循环。每次迭代,减少数组的结尾;如果它达到0则弹出它,否则退出循环。
    • 或者,这相当于只是弹出数组末尾的所有1,然后递减数组的结尾。
  • 当您看到一个数字时,写出结果的堆栈深度并将数字添加到堆栈的末尾。
  • 当您到达输入的末尾时,请验证堆栈是否为空。

Here's code to do this:

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());