Algorithm Scala提取列表中相差1(整数)的邻居

Algorithm Scala提取列表中相差1(整数)的邻居,algorithm,scala,extract,Algorithm,Scala,Extract,我目前正试图从一个列表中找出与我相差1的邻居。例如,如果我的列表如下所示: List(1,2,3,7,8,10,13,14) //By extracting I want to get: List( List(1,2,3), List(7,8), List(10), List(13,14) ) 我自己也试过做foldLeft,我觉得我离得很近,但离得很远。有人能帮我吗?有什么建议吗^^ 非常感谢!:) 这里有一个使用foldRight的解决方案: val

我目前正试图从一个列表中找出与我相差1的邻居。例如,如果我的列表如下所示:

List(1,2,3,7,8,10,13,14)
//By extracting I want to get:
List(
    List(1,2,3),
    List(7,8),
    List(10),
    List(13,14)
    )
我自己也试过做foldLeft,我觉得我离得很近,但离得很远。有人能帮我吗?有什么建议吗^^
非常感谢!:)

这里有一个使用foldRight的解决方案:

val oldList = List(1, 2, 3, 7, 8, 10, 13, 14)

val newList = oldList.foldRight[List[List[Int]]](Nil)((a, b) => b match {
  case (bh @ bhh :: _) :: bt if (bhh - a == 1) => (a :: bh) :: bt
  case _ => (a :: Nil) :: b
})
因此,我们向后迭代条目,并根据差异是否为1,将其前置到现有的标题列表或添加新的标题列表:

Nil
(14, ...) => (14 :: Nil) :: Nil
(13, ...) => (13 :: 14 :: Nil) :: Nil
(10, ...) => (10 :: Nil) :: (13 :: 14 :: Nil) :: Nil
...

我已经有一段时间没有使用Scala了,所以这可能不是最好的解决方案,但我希望您能理解。

这里有一个使用
foldRight
的解决方案:

val oldList = List(1, 2, 3, 7, 8, 10, 13, 14)

val newList = oldList.foldRight[List[List[Int]]](Nil)((a, b) => b match {
  case (bh @ bhh :: _) :: bt if (bhh - a == 1) => (a :: bh) :: bt
  case _ => (a :: Nil) :: b
})
  //First Part: Separates the list into ordered pairs with tail - head == 1
  val ls = List(1,2,3,7,8,10,13,14)

  val lb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- ls.sorted.sliding(2)) {
    if (right - left == 1) {
      lb += List(left, right)
    }else {
      if(!lb.flatten.toList.contains(left)) lb += List(left)
    }
  }

  println(lb.toList)

  //Second Part: Merges ordered pairs (x1, y1) and (x2, y2) when y1 == y2
  val finalLb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- lb.toList.sliding(2)) {
    if(left.tail.contains(right.head)) {
      finalLb += (left ++ right).distinct
    }else{
      finalLb += right
    }
  }

  println(finalLb.toList)
因此,我们向后迭代条目,并根据差异是否为1,将其前置到现有的标题列表或添加新的标题列表:

Nil
(14, ...) => (14 :: Nil) :: Nil
(13, ...) => (13 :: 14 :: Nil) :: Nil
(10, ...) => (10 :: Nil) :: (13 :: 14 :: Nil) :: Nil
...

我已经有一段时间没有使用Scala了,所以这可能不是最好的解决方案,但我希望您能理解。

连续整数将随着列表索引的增加而增加,因此我们可以减去索引,它们将形成相同数量的组

  //First Part: Separates the list into ordered pairs with tail - head == 1
  val ls = List(1,2,3,7,8,10,13,14)

  val lb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- ls.sorted.sliding(2)) {
    if (right - left == 1) {
      lb += List(left, right)
    }else {
      if(!lb.flatten.toList.contains(left)) lb += List(left)
    }
  }

  println(lb.toList)

  //Second Part: Merges ordered pairs (x1, y1) and (x2, y2) when y1 == y2
  val finalLb: ListBuffer[List[Int]] = new ListBuffer[List[Int]]()

  for (List(left,right) <- lb.toList.sliding(2)) {
    if(left.tail.contains(right.head)) {
      finalLb += (left ++ right).distinct
    }else{
      finalLb += right
    }
  }

  println(finalLb.toList)
val li = List(1, 2, 3, 7, 8, 10, 13, 14)
val groups = li.zipWithIndex.groupBy({case (e, i) => e - i})  // group numbers
groups.values.toList.map(_.map(_._1))  // drop indices and grouping keys

注意:这些将丢失无序初始列表的顺序。对于您的情况,您可以使用
重新排序。sortBy(u.head)

连续整数将根据列表索引递增,因此我们可以减去索引,它们将形成相同数字的组

val li = List(1, 2, 3, 7, 8, 10, 13, 14)
val groups = li.zipWithIndex.groupBy({case (e, i) => e - i})  // group numbers
groups.values.toList.map(_.map(_._1))  // drop indices and grouping keys

注意:这些将丢失无序初始列表的顺序。就你的情况而言,你可以用
.sortBy(u.head)

重新排序,显示你有多接近……显然你的问题充满了讽刺,但仍然是。初始值为List(List(Int))时,我尝试将其折叠并匹配值(看看它们是否相差1)。但创建新的列表似乎不起作用。编译器抛出一个错误。那就是我离得有多近。我觉得这是一种正确的方法,但我对函数式编程还是相当陌生的。这并不具有讽刺意味。请查看此建议,以备将来参考:另请查看其中可能不是完全重复的内容,因为这更具体,并且可以进行优化。显示您有多接近……显然,您的问题充满了讽刺,但仍然存在。初始值为List(List(Int))时,我尝试将其折叠并匹配值(看看它们是否相差1)。但创建新的列表似乎不起作用。编译器抛出一个错误。那就是我离得有多近。我觉得这是一种正确的方法,但我对函数式编程还是相当陌生的。这并不具有讽刺意味。只需查看此建议以供将来参考:还可以查看哪些建议可能不是完全重复的,因为这更具体,可以优化很酷!谢谢^^酷!谢谢^^哇!只有两行!谢谢大家!^^哇!只有两行!谢谢大家!^^