我仍然是Scala的新手,但我正在尝试确定一个数组是否有任何连续的整数,如果它有,那么它有多少。这是我到目前为止所做的,但我还没有完成它。
def isConsecutive(seq: Array[Int]): (Boolean, Int) = {
var arr: Array[Int] = Array[Int]()
for((v, i) <- seq.zipWithIndex) {
if (i < seq.length()) {
if (v + 1 == seq(i + 1)) {
arr = arr :+ v
}
}
}
var res = if (arr.length() < 1) true else false
return (res, arr.length())
}
我只想返回一个布尔值,表示数组是否有连续的整数,即1,2,3,以及连续整数的数量是否为零。
答案 0 :(得分:6)
def isConsecutive(seq: Array[Int]): (Boolean, Int) = {
val count = seq.sliding(2).count(a => a(0)+1 == a(1))
(count > 0, count)
}
并测试它:
scala> isConsecutive(Array(3,5,8,99))
res0: (Boolean, Int) = (false,0)
scala> isConsecutive(Array(3,4,5,8,99))
res1: (Boolean, Int) = (true,2)
scala> isConsecutive(Array(3,4,5,98,99))
res2: (Boolean, Int) = (true,3)
答案 1 :(得分:2)
如果需要检查始终以1开头的整数,并且始终从第一个元素开始:
scala> List(1,2,3,4,5,8,9).zipWithIndex.takeWhile(x => x._1 == x._2 + 1).size
res45: Int = 5
*您可以使用res45 == 0
检查您的情况,无需额外Boolean
或者,如果您想要任何具有连续整数的子序列中的所有元素计数:
case class Counter(v: Int, counters: List[Int], prevElem: Int)
def conseq(l: List[Int]) = {
val r = l.tail.foldLeft(Counter(0,List.empty,l.head)){(acc, el) =>
if (el - acc.prevElem == 1) Counter(acc.v + 1, acc.counters, el)
else if (acc.v == 0) acc.copy(prevElem = el)
else Counter(0, acc.v + 1 :: acc.counters, el)
}
r.counters.reverse ++ List(r.v).filter(0!=)//linear time; you might consider Vector or something instead of List
}
scala> conseq(List(1,2,3,4,100,105,106,107))
res44: List[Int] = List(4, 3)
您还可以按照子序列收集初始值(如上例中的1和105)及其指标(如前例中的0和5) - 您也可以在Counter内部进行。
答案 2 :(得分:1)
以下解决方案将尝试识别最长的连续整数,而不仅仅是存在多少个连续对。对于后一个问题,来自@jwvh的解决方案非常棒。
我们的想法是拥有一个Result
类型,您可以将其折叠并相应地更新:
case class Result(prev: Int, curMax: Int = 0, max: Int = 0) {
/* process takes the next int and updates the result up to that point */
def process(n: Int) = {
val newRunningMax = if(n==(prev+1)) curMax + 1 else 0
Result(n, newRunningMax, Math.max(max, newRunningMax))
}
}
def findLongestConsecutiveSeq(data: Array[Int]): (Boolean, Int) = {
require(data.nonEmpty, "Only works with non empty arrays")
val res = data.tail.foldLeft(Result(data.head))( (p,n) => p.process(n) )
if(res.max > 0) (true, res.max + 1) // max = consecutive pairs (+1 for length)
else (false, 0)
}
在REPL中进行测试:
findLongestConsecutiveSeq(Array(1,2,3,4,5,8,9))
res1: (Boolean, Int) = (true, 5)
findLongestConsecutiveSeq(Array(1,3,3,4,5,8,9))
res2: (Boolean, Int) = (true, 3)
findLongestConsecutiveSeq(Array(3,2,2,2))
res3: (Boolean, Int) = (false, 0)
findLongestConsecutiveSeq(Array(0,1,2,3,4,5,6,6,6,6,7,8,9,10,11,12,13))
res4: (Boolean, Int) = (true, 8)
答案 3 :(得分:1)
测量最长一段连续整数的长度,类似于当前答案,但是作为简单的尾递归实现:
def countConsecutive(s: Seq[Int]) = {
@tailrec
def countConsecutiveRecurse(maxLen: Int, s: Seq[Int], currLen: Int, currVal: Int): Int = s match {
case Seq() => maxLen max currLen
case head +: tail =>
if (head == currVal + 1) countConsecutiveRecurse(maxLen, tail, currLen + 1, head)
else countConsecutiveRecurse(maxLen max currLen, tail, 1, head)
}
countConsecutiveRecurse(0, s, 0, 0)
}