Scala数组操作任务需要两个指针[Scala]

时间:2018-03-14 23:00:08

标签: scala

我有一个更新scala数组的任务:

val input = Seq[2, 1, 5, 4, 5, 1, 8, 4]

input是需要更新的数组。 label是索引,应该相应地更新数组中的元素。 元素的更新规则是

new_value = the_current_value + value_of_last_labeled_elements

例如,如果

val label = Seq(2)

那么期望的结果应该是

input = Seq(2,1,5,4,5,1,8,4)
output = Seq(2,1,5,9,10,6,13,9)

可能有多个标签:

val label = Seq(2,5)

然后期望的结果应该是:

input = Seq(2,1,5,4,5,1,8,4)
output = Seq(2,1,5,9,10,6,9,5)

第五个元素5被更改为6,因为最后标记的元素是5.从第六个元素开始,它们的值通过加1来更新,因为原始数组中的第五个元素是1。

我发现通过在循环中使用两个指针,可以在Java中轻松处理此任务。但是,我不知道Scala如何处理这个问题。

2 个答案:

答案 0 :(得分:1)

scala> def shiftFromIndexBy (input: List[Int], toShiftFrom: List[Int], shiftBy: Int = 0) : List [Int] = (input, toShiftFrom) match {
     |     case (Nil, _) => Nil
     |     case (x :: xs, Nil) => input.map (_ + shiftBy)
     |     case (x :: xs, y:: ys) => if (y == 0) x + shiftBy :: shiftFromIndexBy (xs, ys.map (_ - 1), x) else
     |         x + shiftBy :: shiftFromIndexBy (xs, toShiftFrom.map(_ - 1), shiftBy)
     | }
shiftFromIndexBy: (input: List[Int], toShiftFrom: List[Int], shiftBy: Int)List[Int]

scala> shiftFromIndexBy (input, label)
res19: List[Int] = List(2, 1, 5, 9, 10, 6, 13, 9)

scala> shiftFromIndexBy (input, List (2, 5))
res20: List[Int] = List(2, 1, 5, 9, 10, 6, 9, 5)

有3个案例,最后一个有两个子类。

  • 案例0:输入为空。完成。
  • 案例1:输入有效,但索引列表中没有更多的转移,该列表为空。然后将执行值添加到List的其余部分 - 完成。
  • 案例2a:我们在索引列表中有值。如果第一个为零,我们必须最终将第一个输入值移动到所携带的数字。我们得到第一个值x作为新的shiftBy值。索引必须减少一个。
  • 案例2b:第一个索引不为零,所以我们继续添加旧的shiftBy值,减少列表其余部分的索引值。

对于大量输入和少量索引值,可以考虑计算一次使用shiftBy值进行变换并一次减小索引值的值的数量。但首先让事情发挥作用,然后让它们变得快速。

为方便起见,我使用了Lists,而不是Seq来实现。

答案 1 :(得分:1)

我想看看我是否可以在没有递归的情况下做到(当然,没有指针)。

def updateAfterIndex(input:Seq[Int], label: Seq[Int]): Seq[Int] = {
  if (label.isEmpty) input
  else {
    val pad = Seq.fill(label.head + 1)(0) ++
      (label :+ input.length - 1).sliding(2)
        .flatMap { case Seq(a, b) => Seq.fill(b - a)(input(a)) }

    input.zip(pad).map(t => t._1 + t._2)
  }
}

它似乎适用于许多不良label内容的例子,例如索引超出范围或顺序错误。

updateAfterIndex(Seq(2,1,5,4,5,1,8,4), Seq())     //res0: Seq[Int] = List(2, 1, 5, 4, 5, 1, 8, 4)
updateAfterIndex(Seq(2,1,5,4,5,1,8,4), Seq(2))    //res1: Seq[Int] = List(2, 1, 5, 9, 10, 6, 13, 9)
updateAfterIndex(Seq(2,1,5,4,5,1,8,4), Seq(2,5))  //res2: Seq[Int] = List(2, 1, 5, 9, 10, 6, 9, 5)
updateAfterIndex(Seq(2,1,5,4), Seq(5,2))          //res3: Seq[Int] = List(2, 1, 5, 4)