使用scala计算字符串中的字符频率

使用scala计算字符串中的字符频率,scala,Scala,我寻找一种方法来计算字符串中的不同字符。 问题是不允许使用scala api中的任何函数或使用VAR(仅限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) 在每次尝试中,我最后都有一个

我寻找一种方法来计算字符串中的不同字符。 问题是不允许使用scala api中的任何函数或使用VAR(仅限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)
在每次尝试中,我最后都有一个
列表[(Char,Int)]
我必须更改Int。但因为它是一个不可变的列表,所以我无法更改它。
如何实现计数字符算法?

您可以使用以下代码段:

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)
val-fruit:String=“dasisteintest”
val map=scala.collection.mutable.HashMap.empty[Char,Int]
对于(symbol您所说的“没有来自Scala API的函数”是什么意思?这是否包括没有来自collections API的函数?如果是,请忽略我的答案。但是,如果我们甚至不能使用reduce方法,我看不出此练习的意义

以下是我的想法:

val fruit: String = "dasisteintest"
fruit.foldLeft[Map[Char,Int]](Map.empty)((map, c) => map + (c -> (map.getOrElse(c, 0) + 1)))
虽然你能扩展你所说的“你必须改变Int”的意思吗

测试:

这里使用的是scala api中的
映射。应用
映射。清空
列表。:
。不使用scala api中的任何函数都很困难。我猜你不应该使用
groupBy
之类的东西,你应该做一些更低级的事情。折叠是自然的解决方案在这里,类似于
foldLeft
,但如果考虑“使用scalaapi中的函数”,您可以自己实现
foldLeft
,就像我在解决方案中所做的那样

对于
withDefaultValue
您可以用显式检查值是否存在来替换它,并在该情况下在那里输入1

您不知道如何更改不可变的列表或映射中的值?您只需使用更改的值创建一个新列表

对于地图,给定

val map = Map('a' -> 3)
你可以更新它做什么

@ map.updated('a', 4) 
res6: Map[Char, Int] = Map('a' -> 4)

两者都执行完全相同的操作-插入或更新-并返回新地图

在这里,您可以找到如何更新列表中的元素

虽然您很少希望按索引访问列表,但您只需要在旧列表的基础上构建一个新列表,同时以某种方式对其进行迭代,例如使用fold。

以下是预期的代码。 首先是从列表中返回字符的函数

    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()

objectcounteachcharinstring
{
//计算输入字符串中特定字符的数目
def characterCount(inputChar:Char,str:String):单位=
{
var num:Int=0
num=str.count(==inputChar);
/*
//计数法的实现

for(谢谢,但是.foldLeft和.getOrElse是scala api中的函数,不是吗?如果我想像你一样实现它,我必须自己编写这些函数……你对scala api的定义是什么?定义只是“不要使用scala api中的函数”"…你认为函数之间有什么区别吗?嗯,是的,很酷,谢谢!我认为自己编写contains方法并不难。我现在就试试。我猜答案不应该使用可变集合,但只有OP知道确切的答案。@问题倒数第二句中的原型paul表示集合应该更改。@theoretisch您可以使用Java的
HashMap
(这绝对不是scala api)为了不实现
contains
+=
方法。@Aliaxander,可以这样做。不过,我想OP还不知道如何使用不可变集合来实现这一点,只是不知道如何在不修改列表的情况下实现。我猜这就是赋值的重点。既然不允许使用变量,我想我s的可变集合也不是。不清楚您的实际问题是什么。假设您不是在有人为您回答任务之后,您被困在哪里了?输出应该是什么样子?
Map
(和
groupBy
)是scala api的一部分,因此不清楚您想要什么。您可以使用什么?正如我在上面所写的,我需要相同的结果,如
fruit.groupBy(identity.mapValues(uu.size)
,但没有来自scala api的函数。我所有的尝试都失败了,因为每次我都需要更改列表中的一个元素。我知道我“只”必须用更改的元素创建一个新列表。但是我不知道如何用更改的元素创建一个新列表。因此我希望有人能帮助我更改列表中的一个元素(没有api中的函数)或者有人有其他方法来计算字符串中的不同字符…希望现在一切都清楚了?谢谢,匹配的解决方案很酷。这完美地解决了我的列表问题。问题清楚地指出,“不允许…使用vars(仅
val
)”。虽然本准则可以回答该问题,但提供关于本准则为什么和/或如何回答该问题的附加上下文可提高其长期价值。
@ map.updated('a', 4) 
res6: Map[Char, Int] = Map('a' -> 4)
@ map + ('a' -> 4) 
res7: Map[Char, Int] = Map('a' -> 4)
    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)
       }
    }
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);
    }
  }
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...^^&&&&")
  }
}