我有两个列表:List(1,1,1) , List(1,0,1)
我想得到以下内容:
每个元素的计数,其中包含第一个列表中的1和相应位置中相应列表中的0,反之亦然。 在上面的示例中,这将是1,0,因为第一个列表在中间位置包含1,而第二个列表在相同位置(中间)包含0。
每个元素的计数,其中1在第一个列表中,1也在第二个列表中。 在上面的例子中,这是两个,因为每个相应的列表中有两个1。我可以使用类List的交叉方法来获得它。
我只是在寻找上述第1点的答案。我可以使用迭代方法来计算项目,但是有更实用的方法吗? 这是整个代码:
class Similarity {
def getSimilarity(number1: List[Int], number2: List[Int]) = {
val num: List[Int] = number1.intersect(number2)
println("P is " + num.length)
}
}
object HelloWorld {
def main(args: Array[String]) {
val s = new Similarity
s.getSimilarity(List(1, 1, 1), List(1, 0, 1))
}
}
答案 0 :(得分:11)
第一个:
scala> val a = List(1,1,1)
a: List[Int] = List(1, 1, 1)
scala> val b = List(1,0,1)
b: List[Int] = List(1, 0, 1)
scala> a.zip(b).filter(x => x._1==1 && x._2==0).size
res7: Int = 1
第二个:
scala> a.zip(b).filter(x => x._1==1 && x._2==1).size
res7: Int = 2
答案 1 :(得分:7)
您可以轻松统计所有组合,并将其放在带有
的地图中def getSimilarity(number1 : List[Int] , number2 : List[Int]) = {
//sorry for the 1-liner, explanation follows
val countMap = (number1 zip number2) groupBy (identity) mapValues {_.length}
}
/*
* Example
* number1 = List(1,1,0,1,0,0,1)
* number2 = List(0,1,1,1,0,1,1)
*
* countMap = Map((1,0) -> 1, (1,1) -> 3, (0,1) -> 2, (0,0) -> 1)
*/
技巧是常见的
// zip the elements pairwise
(number1 zip number2)
/* List((1,0), (1,1), (0,1), (1,1), (0,0), (0,1), (1,1))
*
* then group together with the identity function, so pairs
* with the same elements are grouped together and the key is the pair itself
*/
.groupBy(identity)
/* Map( (1,0) -> List((1,0)),
* (1,1) -> List((1,1), (1,1), (1,1)),
* (0,1) -> List((0,1), (0,1)),
* (0,0) -> List((0,0))
* )
*
* finally you count the pairs mapping the values to the length of each list
*/
.mapValues(_.length)
/* Map( (1,0) -> 1,
* (1,1) -> 3,
* (0,1) -> 2,
* (0,0) -> 1
* )
然后您需要做的就是在地图上查找
答案 2 :(得分:2)
Jatin提出的几乎相同的解决方案,除了您可以使用List.count
以获得更好的可用性:
def getSimilarity(l1: List[Int], l2: List[Int]) =
l1.zip(l2).count({case (x,y) => x != y})
答案 3 :(得分:2)
a.zip(b).filter(x => x._1 != x._2).size
答案 4 :(得分:1)
您也可以使用foldLeft。假设没有非负数:
a.zip(b).foldLeft(0)( (x,y) => if (y._1 + y._2 == 1) x + 1 else x )
答案 5 :(得分:0)
1)您可以zip
2个列表获取(Int, Int)
列表,仅收集(1, 0)
和(0, 1)
对,将(1, 0)
替换为1
}和(0, 1)
与-1
并得到总和。如果(1, 0)
的计数和(0, 1)
的计数相同,则sum
将相等0
:
val (l1, l2) = (List(1,1,1) , List(1,0,1))
(l1 zip l2).collect{
case (1, 0) => 1
case (0, 1) => -1
}.sum == 0
您可以使用view
方法来阻止创建中间集合。
2)您可以使用filter
和length
来计算具有某些条件的元素:
(l1 zip l2).filter{ _ == (1, 1) }.length
(l1 zip l2).collect{ case (1, 1) => () }.length