String 字符串逻辑错误中的Scala计数字符
代码如下:String 字符串逻辑错误中的Scala计数字符,string,scala,count,char,String,Scala,Count,Char,代码如下: val a = "abcabca" a.groupBy((c: Char) => a.count( (d:Char) => d == c)) 以下是我想要的结果: scala.collection.immutable.Map[Int,String] = Map(2 -> b, 2 -> c, 3 -> a) 但我得到的结果是 scala.collection.immutable.Map[Int,String] = Map(2 -> bcbc
val a = "abcabca"
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
以下是我想要的结果:
scala.collection.immutable.Map[Int,String] = Map(2 -> b, 2 -> c, 3 -> a)
但我得到的结果是
scala.collection.immutable.Map[Int,String] = Map(2 -> bcbc, 3 -> aaa)
为什么??
多谢各位 写一个表达式,如
"abcabca".groupBy(identity).collect{
case (k,v) => (k,v.length)
}
这将输出为
res0: scala.collection.immutable.Map[Char,Int] = Map(b -> 2, a -> 3, c -> 2)
让我们分析一下您最初的尝试:
a.groupBy((c: Char) => a.count( (d:Char) => d == c))
那么,你是按什么东西分组的?a.count(…)的结果,因此映射的键将是Int。对于字符a,我们将得到3,对于字符b和c,我们将得到2
现在,将遍历原始字符串,并逐字符累加结果
因此,在遍历第一个“ab”之后,当前状态为“2->b,3->c”。(请注意,对于字符串中的每个字符,都会调用.count(),这是一种浪费n²的算法,但无论如何)
逐步遍历字符串,最后显示累积结果。事实证明,3“a”是在“3”键下发送的,b和c是按照字符串的遍历顺序发送到键“2”,即从左到右的顺序
现在,列表上常见的groupBy返回类似Map[T,list[T]]的内容,因此您可能希望在某个地方有一个list[Char]。它不会发生(因为字符串的Repr是String),并且您的字符列表被有效地重新编译成一个字符串,并作为字符串提供给您
这就是你的最终结果 您的问题标题显示为“字符串逻辑错误中的Scala计数字符”。但您使用的是地图,并且希望将计数作为键。贴图对象中不允许使用相等的关键点。因此,在生成的贴图中消除相等的关键点,只保留一个,因为不允许重复关键点。您需要的可能是类似(count,char)的列表[Int,char]的元组序列。试试这个
val x = "abcabca"
x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}
在Scal REPL中:
上面给出了一个计数列表和相应的字符作为元组列表
如果尝试将其转换为地图:
scala> x.groupBy(identity).mapValues(_.size).toList.map{case (x,y)=>(y,x)}.toMap
res14: scala.collection.immutable.Map[Int,Char] = Map(2 -> c, 3 -> a)
这显然不是你想要的
更简洁地使用:
x.distinct.map(v=>(x.filter(_==v).size,v))
scala> x.distinct.map(v=>(x.filter(_==v).size,v))
res19: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((3,a), (2,b), (2,c))
您的方法的问题是将计数映射到字符。即: 万一
val str=abcabca
当遍历字符串str时,a有计数3,b有计数2,c有计数2,同时创建映射(使用groupBy),它将把所有字符放在值中,该值具有相同的键
Map(3->aaa, 2->bc)
这就是为什么您的程序会得到这样的输出
正如您在groupBy函数的定义中所看到的:
def
groupBy[K](f:(A)⇒ K) :不可变。映射[K,Repr]
根据某个鉴别器函数将此可遍历集合划分为可遍历集合的映射。
注意:此方法不会由视图重新实现。这意味着当应用于视图时,它将始终强制该视图并返回一个新的可遍历集合。
K
鉴别器函数返回的键的类型。
F
鉴别器功能。
返回
从关键点到可遍历集合的映射,以使以下不变量保持不变:
(xs groupBy f)(k)=xs过滤器(x=>f(x)=k)
也就是说,每个键k都绑定到f(x)等于k的元素x的可遍历集合
GroupBy返回一个包含以下不变量的映射
(xs groupBy f)(k) = xs filter (x => f(x) == k)
这意味着它返回键相同的元素集合
“abcabca”.groupBy(identity).map(x=>(x._1,x._2.length))
这是我的编码问题的解决方案,但为什么我的初始逻辑是错误的?map(2->b,2->c)
不是一个映射,因为这组键不是一个集合。@kailena如果它回答了您的问题,请接受这个解决方案一个较短的方法:“abcabca”.groupBy(identity).mapValues(u.length)
是的,非常感谢chaitanya和james。你能告诉我为什么我的逻辑不正确吗?为什么我的代码输出是一组字符而不是单个字符?例如@kaileena如果回答了你的问题,请接受解决方案。thanks@ChaitanyaWaikar您已经为反向映射编写了代码。这是char toInt,它需要另一种方式!!你能做些改变吗。
(xs groupBy f)(k) = xs filter (x => f(x) == k)