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)