如何确定数组是否有连续的整数,如果有,有多少?

时间:2016-02-10 01:10:53

标签: arrays scala

我仍然是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,以及连续整数的数量是否为零。

4 个答案:

答案 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)
  }