我有一个包含重复数字的Scala列表。我想计算特定数字重复的次数。例如:
val list = List(1,2,3,3,4,2,8,4,3,3,5)
val repeats = list.takeWhile(_ == List(3,3)).size
val repeats
等于2
。
显然上面是伪代码,takeWhile
将找不到两个重复的3
,因为_
代表一个整数。我尝试混合takeWhile
和take(2)
,但收效甚微。我还引用了How to find count of repeatable elements in scala list的代码,但似乎作者希望实现不同的东西。
感谢您的帮助。
答案 0 :(得分:4)
这适用于这种情况:
val repeats = list.sliding(2).count(_.forall(_ == 3))
sliding(2)方法为您提供元素和后继列表的迭代器,然后我们只计算这两个等于3的位置。
问题是它是否为List(3,3,3)创建了正确的结果?你想要那个是2还是只重复1次。
答案 1 :(得分:1)
val repeats = list.sliding(2).toList.count(_==List(3,3))
更一般地,以下代码返回element的元组并为所有元素重复值:
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))))
在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))
即使滑动值也可以通过定义以下函数来改变:
def repeatsByTimes(list:List[Int],n:Int) =
list.distinct.map(x=>(x,list.sliding(n).toList.count(_.forall(_==x))))
现在处于REPL:
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) }
在SCALA REPL中:
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>
这些结果可以理解如下:
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 :(得分:0)
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
其中runLength的定义如下scala's 99 problems problem 9和scala's 99 problems problem 10。
由于numberOfNs
和runLengthPerN
为Maps
,您可以使用numberOfNs(number)
获取列表中任意数字的人口数,并连续获取最长重复次数的长度runLengthPerN(number)
。要获得runLength
,只需使用runLength(list).map{ t => t._2 -> t._1 }
进行计算。
答案 3 :(得分:0)
感谢Luigi Plinge我能够使用游程编码中的方法将重复列表中的项目组合在一起。我在此处使用了此页面中的一些代码段:http://aperiodic.net/phil/scala/s-99/
var n = 0
runLengthEncode(totalFrequencies).foreach{ o =>
if(o._1 > 1 && o._2==subjectNumber) n+=1
}
n
方法runLengthEncode
如下:
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) }
我不完全满意我需要使用mutable var n
来计算出现次数,但它确实有效。这将计算一个数字重复的次数,无论它重复多少次。
答案 4 :(得分:0)
如果您知道列表不长,则可以使用字符串来完成。
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
答案 5 :(得分:0)
从你的伪代码我得到了这个工作:
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
我无法理解您是否还要查看多个尺寸的列表,然后您需要将参数更改为sliding
到所需的尺寸。