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/でこのコードを実行すると、すべてが機能しますが、自宅の PC で試してみるとエラーが発生するため、次のように変更しました。

     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

vals と vars を使わずに再帰的な答えを書くことができます。ほとんどのコードは、無効な入力を防ぐためのものです。

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 に進み、1 ではなく 0 から進みます。代わりに s(j) を使用することもできます。

次のステップでは、中間リストを取り除きます。

  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 
  }

返品を簡素化しました。while の代わりに for ループを使用しましょう。

  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 に答える