0

作为 Scala 的初学者,我偶然发现了一个似乎无法解决的问题。基本上,我从我设法添加到列表的文件中获得坐标,然后将所有这些值排序到不同的列表中,如下所示:

List(List(61, 62, 63, 64, 65, 66, 67), List(21, 23, 25, 26, 27))

通过使用此代码:

val lines = io.Source.fromFile("in.txt").getLines

val coordinates =
  lines
    .drop(0)
    .toList
    .sortWith(_<_)
    .mkString
    .replaceAll("\\s", "")
    .grouped(2)
    .toList

val conditions = 1 to 5000

val que = coordinates.map(_.toInt)

val thisIsIt = conditions.foldLeft(List():List[List[Int]])((acc, elem) =>
  que
    .filter(_.toString.startsWith(elem.toString))::acc)
    .filterNot(_.isEmpty)
    .filter(_.length > 3)
    .map(_.toList)

我要做的是在每个列表中找到遵循相同模式的坐标。例如,在列表中

List(21, 23, 25, 26, 27) 

我想删除元素“26”,因为相邻值之间的差异应该是“2”。

23-21 = 2
25-23 = 2
26-25 = 1, 

但是如果我们检查 26 之后的下一个元素与前一个元素 25 之间的差异,我们可以看到:

27-25 = 2

因此,如果删除 26,则每个相邻值之间的差应为“2”的条件变为真,给我们列表

List(21, 23, 25, 27)

另一个列表是:

List(61, 62, 63, 64, 65, 66, 67) 

应该只返回相同的列表,因为元素之间的差异是恒定的并且它是“1”。

最后我应该把名单还给我

List(List(61, 62, 63, 64, 65, 66, 67), List(21, 23, 25, 27))

我将用列表举另一个例子

List(31, 32, 33, 36, 37)

虽然前 3 个元素之间的差异确实是“1”,并且对于最后 2 个元素之间的差异也可以这样说,但是没有办法从列表的开头遍历到列表的末尾,并且值之间的差异是恒定的.

坐标可以改变,每个列表中的值的数量也可以改变。任何帮助将不胜感激,因为我已经死了。我尝试使用使用headtail的函数,遍历列表并应用条件,但似乎没有任何效果。

提前致谢!

4

2 回答 2

0

听起来您可能只想将每个元素减少List[Int]到只有那些等距的元素(如果有的话),从开始到结束都包含在内。

这是我的看法。

val input = List(List(61, 62, 63, 64, 65, 66, 67)
               , List(31, 32, 33, 36, 37)
               , List(21, 23, 25, 26, 27)
               , List(2, 12, 19, 22, 36))

val result = input.map{ lst =>
  val hd = lst.head
  val end = lst.last
  val distance = end - hd
  Stream.from(1).take(distance/2).flatMap{ step =>
    val rng = hd to end by step
    if (distance%step == 0 && rng.diff(lst).isEmpty)
      Some(rng.toList)
    else None
  }.headOption.getOrElse(Nil)
}
//result: List[List[Int]] = List(List(61, 62, 63, 64, 65, 66, 67)
//                             , List()
//                             , List(21, 23, 25, 27)
//                             , List(2, 19, 36))

注意:这假设 eachList[Int]是有序的,或者至少.last假设 大于.head

于 2018-10-24T07:08:46.127 回答
0

我仍然不知道我是否理解你想要做什么。这就是我认为您可能的意思:找到给定列表的最长可能子列表,包含原始列表的至少三个元素,包括第一个和最后一个元素,使得每个连续元素之间的距离是恒定的。

在这种情况下,这是一个简单的解决方案。基本上,首先你找出所有可能的距离(通过从每个元素中减去列表的头部,并保持这些值为正的,但不大于列表头部和尾部之间距离的一半),然后你尝试为这些距离中的每一个构造生成的子列表。

  def findIt(list: List[Int]) = {
    @tailrec def doIt(
      list: List[Int],
      candidates: List[Int],
      last: Int 
    ): Option[List[Int]] = candidates match {
       case Nil => None
       case dist :: rest => 
         val result = list.foldLeft[List[Int]](Nil) {
           case (Nil, x) => List(x)
           case (l@(head :: _), x) if x == head + dist => x :: l
           case (l, _) => l
         }
         if(result.head == last) Some(result.reverse) 
         else doIt(list, rest, last)
    }

    val candidates = list.foldLeft[List[Int]](Nil) { 
       case (Nil, x) => List(0)
       case (l, x) => (x - list.head) :: l
    }
    if(list.nonEmpty) doIt(
     list, 
     candidates.filter(x => x > 0 && x <= candidates.head/2).reverse, 
     list.head + candidates.head
    ) else None
 }
于 2018-10-23T15:30:15.210 回答