如何在Scala列表中找到重复项?

如何在Scala列表中找到重复项?,scala,Scala,我有一个Scala列表,其中包含一些重复的数字。我想计算一个特定的数字会重复自身的次数。例如: val list = List(1,2,3,3,4,2,8,4,3,3,5) val repeats = list.takeWhile(_ == List(3,3)).size 而val重复将等于2 显然,上面的代码是伪代码,takeWhile将不会找到两个重复的3s,因为表示一个整数。我尝试将takeWhile和take(2)混合使用,但几乎没有成功。我还引用了来自的代码,但似乎作者希望实现一些不

我有一个Scala列表,其中包含一些重复的数字。我想计算一个特定的数字会重复自身的次数。例如:

val list = List(1,2,3,3,4,2,8,4,3,3,5)
val repeats = list.takeWhile(_ == List(3,3)).size
而val
重复
将等于
2

显然,上面的代码是伪代码,
takeWhile
将不会找到两个重复的
3
s,因为
表示一个整数。我尝试将
takeWhile
take(2)
混合使用,但几乎没有成功。我还引用了来自的代码,但似乎作者希望实现一些不同的功能

感谢您的帮助。

def包[A](ls:List[A]):List[List[A]={
def pack[A](ls: List[A]): List[List[A]] = {
  if (ls.isEmpty) List(List())
  else {
    val (packed, next) = ls span { _ == ls.head }
    if (next == Nil) List(packed)
    else packed :: pack(next)
  }
}

def encode[A](ls: List[A]): List[(Int, A)] = pack(ls) map { e => (e.length, e.head) }

val numberOfNs = list.distinct.map{ n =>
  (n -> list.count(_ == n))
 }.toMap

val runLengthPerN = runLengthEncode(list).map{ t => t._2 -> t._1}.toMap

val nRepeatedMostInSuccession = runLengthPerN.toList.sortWith(_._2 <= _._2).head._1
if(ls.isEmpty)List(List()) 否则{ val(压缩,下一个)=ls span{{u==ls.head} if(next==Nil)列表(打包) 打包:打包(下一个) } } def encode[A](ls:List[A]):List[(Int,A)]=pack(ls)map{e=>(e.length,e.head)} val numberOfNs=list.distinct.map{n=> (n->list.count(==n)) }汤玛普先生 val runLengthPerN=runLengthCode(list).map{t=>t.\u 2->t.\u 1}.toMap val nRepeatedMostInAccess=runLengthPerN.toList.sortWith(u._2T._2->t._1}

多亏了我能够在运行长度编码中使用方法将重复列表中的项目组合在一起。我在这里使用了本页中的一些片段:

运行代码的方法如下所示:

  private def pack[A](ls: List[A]): List[List[A]] = {
    if (ls.isEmpty) List(List())
    else {
      val (packed, next) = ls span { _ == ls.head }
      if (next == Nil) List(packed)
      else packed :: pack(next)
    }
  }

  private def runLengthEncode[A](ls: List[A]): List[(Int, A)] =
    pack(ls) map { e => (e.length, e.head) }

我并不完全满意我需要使用可变var
n
来计算出现的次数,但它做到了。这将计算一个数字自身重复的次数,无论重复多少次。

在这种情况下,这将起作用:

val repeats = list.sliding(2).count(_.forall(_ == 3))
滑动(2)方法为您提供元素和后续元素列表的迭代器,然后我们只计算这两个元素等于3的位置


问题是它是否为列表(3,3,3)创建了正确的结果?您希望是重复2次还是仅重复1次。

如果您知道您的列表不是很长,您可以使用字符串进行操作

val list = List(1,2,3,3,4,2,8,4,3,3,5)
val matchList = List(3,3)
(matchList.mkString(",")).r.findAllMatchIn(list.mkString(",")).length

从你的伪代码中,我得到了以下结果:

val pairs = list.sliding(2).toList  //create pairs of consecutive elements
val result = pairs.groupBy(x => x).map{ case(x,y) => (x,y.size);   //group pairs and retain the size, which is the number of occurrences.
result
将是一个
Map[List[Int],Int]
因此您可以像下面这样计算数字:

 result(List(3,3))    // will return 2 
我不明白如果您还想检查多个大小的列表,那么您需要将参数更改为
滑动
到所需的大小

val repeats = list.sliding(2).toList.count(_==List(3,3))
更一般地说,以下代码返回元素的元组,并重复所有元素的值:

scala> list.distinct.map(x=>(x,list.sliding(2).toList.count(_.forall(_==x))))
res27: List[(Int, Int)] = List((1,0), (2,0), (3,2), (4,0), (8,0), (5,0))
这意味着元素“3”在2个位置连续重复2次,所有其他位置重复0次

而且,如果我们希望元素连续重复3次,我们只需要修改代码如下:

list.distinct.map(x=>(x,list.sliding(3).toList.count(_.forall(_==x))))
   1 times the element '1' occurred at 1 places.
   2 times the element '1' occurred at 0 places.
   ............................................
   ............................................
   .............................................
   2 times the element '3' occurred at 6 places..
   .............................................
   3 times the element '3' occurred at 3 places...
   ............................................and so on.
在SCALA REPL中:

scala> val list = List(1,2,3,3,3,4,2,8,4,3,3,3,5)
list: List[Int] = List(1, 2, 3, 3, 3, 4, 2, 8, 4, 3, 3, 3, 5)

scala> list.distinct.map(x=>(x,list.sliding(3).toList.count(_==List(x,x,x))))
res29: List[(Int, Int)] = List((1,0), (2,0), (3,2), (4,0), (8,0), (5,0))
scala> val list = List(1,2,3,3,3,4,2,8,4,3,3,3,2,4,3,3,3,5)
list: List[Int] = List(1, 2, 3, 3, 3, 4, 2, 8, 4, 3, 3, 3, 2, 4, 3, 3, 3, 5)


scala> repeats(list,3)
res38: List[(Int, Int, Int)] = List((1,1,1), (1,2,0), (1,3,0), (2,1,3), 
 (2,2,0), (2,3,0), (3,1,9), (3,2,6), (3,3,3), (4,1,3), (4,2,0), (4,3,0), 
 (5,1,1), (5,2,0), (5,3,0), (8,1,1), (8,2,0), (8,3,0))

scala>
甚至滑动值也可以通过将函数定义为:

def repeatsByTimes(list:List[Int],n:Int) =
list.distinct.map(x=>(x,list.sliding(n).toList.count(_.forall(_==x))))
现在回复:

scala> val list = List(1,2,3,3,4,2,8,4,3,3,5)
list: List[Int] = List(1, 2, 3, 3, 4, 2, 8, 4, 3, 3, 5)

scala> repeatsByTimes(list,2)
res33: List[(Int, Int)] = List((1,0), (2,0), (3,2), (4,0), (8,0), (5,0))

scala> val list = List(1,2,3,3,3,4,2,8,4,3,3,3,2,4,3,3,3,5)
list: List[Int] = List(1, 2, 3, 3, 3, 4, 2, 8, 4, 3, 3, 3, 2, 4, 3, 3, 3, 5)

scala> repeatsByTimes(list,3)
res34: List[(Int, Int)] = List((1,0), (2,0), (3,3), (4,0), (8,0), (5,0))

scala>
我们可以更进一步,比如给定一个整数列表和一个最大数 对于列表中任何元素可能出现的连续重复,我们可能需要一个3元组的列表,表示(元素、该元素的重复次数、重复发生的位置)。这是比上述更详尽的信息。可以通过编写如下函数来实现:

 def repeats(list:List[Int],maxRep:Int) =
 { var v:List[(Int,Int,Int)] = List();
 for(i<- 1 to maxRep)
 v = v ++ list.distinct.map(x=> 
 (x,i,list.sliding(i).toList.count(_.forall(_==x))))
 v.sortBy(_._1) }
这些结果可以理解如下:

list.distinct.map(x=>(x,list.sliding(3).toList.count(_.forall(_==x))))
   1 times the element '1' occurred at 1 places.
   2 times the element '1' occurred at 0 places.
   ............................................
   ............................................
   .............................................
   2 times the element '3' occurred at 6 places..
   .............................................
   3 times the element '3' occurred at 3 places...
   ............................................and so on.

查找“运行长度编码”,因为您想要的是类似的。还有
滑动
方法。它不清楚。结果2可能意味着这个数字重复两次-在一次重复中有两次重复数字3--或--max number(这里也是2)我不认为这正是他想要的。是的,我也不确定。也许他想要一个连续的重复列表?我会加上这个例子,以及一个找到最长重复的例子。我刚刚想出来,我现在提交一个答案:)我想他想要一个函数(list,int)=>int,它将查找作为参数传递的int的最长重复。在他的例子中,for 3希望看到2作为结果。当然,由于,您可以使用
count
方法避免var,或者更一般地说
foldLeft
来回答您的问题,重复1次。不管它重复多长时间。还有,非常简洁的解决方案:)为什么要添加
toList
?它似乎没有任何作用。此外,这与4年前接受的答案几乎相同。在为一个旧问题添加一个答案时,最好指出你的答案与其他答案不同。旧答案是可以的。但这一步概括并重复了所有元素的值。我觉得至少有一点改进。