1

我正在执行以下代码:

def takeN(s : String, n : Int): String = {
    var j = 1
    var o = s.split("")
    if(n != 0){
      var arr = new Array[Char](n)
    }
    while(j <= n){
      arr(j) = o(j)
      j += 1
    }
    val ml = List.fromArray(arr)
    var newS = ml.mkString("")
    newS
  }

当我用这个 takeN("abcd",2) 测试这段代码时,我得到的答案是:

nullab

当我在以下位置运行此代码时:http ://www.simplyscala.com/一切正常,但是当我在家用电脑上尝试时出现错误,因此我将其更改为:

     def takeN(s : String, n : Int): String = {
    var j = 1
    var o = s.split("")
    var arr = new Array[Char](n)
    while(j <= n){
      arr(j) = o(j)
      j += 1
    }
    val ml = List.fromArray(arr)
    var newS = ml.mkString("")
    newS
  }

然后我得到这个错误:

error: type mismatch;
 found   : java.lang.String
 required: Char
             arr(j) = o(j)

我不知道如何解决这个问题。为什么scala这么难??

4

3 回答 3

3

您发布的代码不是非常惯用的 Scala,但该语言内置了以下功能:

scala> "abcd".take(2)
res0: String = ab

如果你真的想要一个具有该签名的方法,你可以这样做:

def takeN(s: String, n: Int) = 
  s.take(n)
于 2012-04-04T16:08:45.543 回答
1

您可以在没有所有 val 和 var 的情况下编写递归答案。大多数代码是为了防止无效输入:

def takeN (s : String, n : Int): String = {
  if (n > s.length) sys.error ("n > s.length: " + n  + " > " + (s.length))
  else if (n < 0) sys.error ("n < 0 : " + n)
  else if (n == 0) ""
  else if (n == s.length) s 
  else s(0) + takeN (s.substring (1), n-1) }

一个较短的解决方案(但没有保护)是:

def takeN (s : String, n: Int): String =
   (0 to n-1).map (s(_)).mkString 

用法:

takeN ("foolish", 5)
res16: String = fooli

但是,让我们尝试一个更接近您的方法的解决方案:

  def takeN (s: String, n: Int): String = {
    var j = 0
    var arr = new Array[Char](n)
    while (j < n) {
      arr (j) = s(j)
      j += 1
    }
    val ml = List.fromArray (arr)
    var newS = ml.mkString("")
    newS
  }

字符串索引(如在 Java 中)从 0 开始,因此我们转到 j < n,而不是 j <= n 并且从 0,而不是 1。我们不需要 'o'(带有可疑的拆分 (""),因为我们也可以使用 s(j) 代替。

下一步,去掉中间的List:

  def takeN (s: String, n: Int): String = {
    var j = 0
    var arr = new Array[Char](n)
    while (j < n) {
      arr (j) = s(j)
      j += 1
    }
    arr.mkString 
  }

我们简化了回报。现在让我们使用 for 循环,而不是 while:

  def takeN (s: String, n: Int): String = {
    val arr = for (j <- (0 to n-1)) yield s(j)
    arr.mkString 
  }

要不就

  def takeN (s: String, n: Int): String =
    (for (j <- (0 to n-1)) yield s(j)).mkString 
于 2012-04-04T16:25:37.253 回答
0

问题是数组从索引 0 开始。这null只是数组元素的初始值。

一个更简单的替代方法是使用标准的 Scala API:

scala> "abcd".take(2)
res0: String = ab
于 2012-04-04T16:09:47.680 回答