我搜索从字符串中计算不同字符的方法。 问题是不允许使用scala-api中的任何函数或使用vars (仅限val)。
我想要那样的结果
val fruit: String = "dasisteintest"
println(fruit.groupBy(identity).mapValues(_.size))
Map(e -> 2, s -> 3, n -> 1, t -> 3, a -> 1, i -> 2, d -> 1)
在我做的每一次尝试中,我最后都有list[(Char,Int)]
,我必须更改Int。但由于它是一个不可改变的列表,我无法改变它。
如何实现计数char算法?
答案 0 :(得分:1)
您可以使用以下代码段:
val fruit: String = "dasisteintest"
val map = scala.collection.mutable.HashMap.empty[Char, Int]
for (symbol <- fruit) {
if (map.contains(symbol))
map(symbol) = map(symbol) + 1
else
map.+=((symbol, 1))
}
println(map)
答案 1 :(得分:1)
def countChars(str: String) = {
def loop(chars: List[Char], acc: Map[Char, Int]): Map[Char, Int] = {
chars match {
case Nil => acc
case char :: rest =>
loop(rest, acc + (char -> (acc(char) + 1)))
}
}
loop(str.toList, Map.empty[Char, Int] withDefaultValue 0)
}
测试:
@ val fruit: String = "dasisteintest"
fruit: String = "dasisteintest"
@ countChars(fruit)
res4: Map[Char, Int] = Map('e' -> 2, 's' -> 3, 'n' -> 1, 't' -> 3, 'a' -> 1, 'i' -> 2, 'd' -> 1)
这里使用的是scala api,Map.apply
或Map.empty
或List.::
。很难不使用scala api中的任何函数。我的猜测是你不应该使用像groupBy
之类的东西,你应该做一些更低级别的事情。折叠是这里的自然解决方案,例如foldLeft
,但是如果考虑使用scala api&#34;中的函数,您可以自己实现foldLeft
,就像我在解决方案中所做的那样
对于withDefaultValue
,您可以使用显式检查来替换它是否存在值,并在那种情况下放置1。
您不知道如何更改不可变的列表或地图?您只需更改该值即可创建一个新列表。
对于地图,给出
val map = Map('a' -> 3)
你可以更新它
@ map.updated('a', 4)
res6: Map[Char, Int] = Map('a' -> 4)
或
@ map + ('a' -> 4)
res7: Map[Char, Int] = Map('a' -> 4)
两者都完全相同 - 插入或更新 - 并返回新地图。
您可以在此处找到如何更新列表中的元素
Replace element in List with scala
虽然您很少想按索引访问列表,但您只需从旧版本中构建一个新列表,同时以某种方式迭代它,例如与折叠。
答案 2 :(得分:0)
“Scala API没有函数”是什么意思?这是否包含来自集合api的函数?如果是这样,那么忽略我的答案。但是,如果我们甚至不能使用reduce方法,我看不出这个练习的重点。
以下是我提出的建议:
val fruit: String = "dasisteintest"
fruit.foldLeft[Map[Char,Int]](Map.empty)((map, c) => map + (c -> (map.getOrElse(c, 0) + 1)))
虽然你可以扩展“你必须改变Int”的意思吗?
答案 3 :(得分:0)
这是预期的代码。 首先是从列表中返回char的函数
def removeFromList(l: List[Char], l2: List[Char], toDelete: Char): List[Char] = {
if (l.isEmpty) l2
else {
if (l.head == toDelete)
removeFromList(l.tail, l2, toDelete)
else
removeFromList(l.tail, l2 :+ l.head, toDelete)
}
}
然后是计算字符并调用removeFromList()
def zaehlZeichen(s: String): List[(Char, Int)] = {
val sl: List[Char] = s.toUpperCase().toList
if (sl.isEmpty) Nil
else {
val l: List[Char] = List()
val tupleList: List[(Char, Int)] = List();
val in: Int = countChar(sl, 0, sl.head)
val t: List[(Char, Int)] = tupleList :+ (sl.head, in)
val cutL: List[Char] = removeFromList(sl, l, sl.head)
t ::: zaehlZeichen(cutL.mkString);
}
}
答案 4 :(得分:0)
object CountEachCharInString
{
//Counts the number of a specific character in the Input String
def characterCount(inputChar: Char, str: String): Unit =
{
var num: Int = 0
num = str.count(_ == inputChar);
/*
//Implementation of count method
for(i <- 0 to str.length - 1)
{
if(str(i) == inputChar)
{
num += 1
}
}
*/
println(s"$inputChar appears $num times")
}
def countAllChars(inputStr: String): Unit =
{
//To eliminate duplicates, need one loop inside the other. str(i) == str(j)
for(i <- 0 to inputStr.length - 1)
{
var occurence: Int = 0
for(j <- 0 to i-1)
{
if(inputStr(j) == inputStr(i))
occurence = occurence + 1
}
if(occurence == 0)
{
characterCount(inputStr(i), inputStr)
//var num = inputStr.count(_ == inputStr(i))
//println( inputStr(i) + s" appears $num times")
}
}
}
def main(args: Array[String]): Unit =
{
countAllChars("HelloforHello...^^&&&&")
}
}