作为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个元素之间的差也可以说是相同的,但是无法通过常数从列表的开头遍历到列表的结尾值之间的差异。
坐标可以更改,每个列表中值的数量也可以更改。任何帮助将不胜感激,因为我已经死了。我尝试使用使用 head 和 tail 的函数,遍历列表并应用条件,但似乎没有任何作用。
谢谢!
答案 0 :(得分: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
}
答案 1 :(得分: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))
注意:这假设每个List[Int]
都被排序,或者至少.last
被假定大于.head
。