0

私はscalaパターンマッチングで遊んでいて、findNext関数を作ろうとしています:

findNext(1,List(1,2,3)) == 2
findNext(2,List(1,2,3)) == 3
findNext(3,List(1,2,3)) == 1

def findNext(needle : Int, haystack : List[Int]): Int = {
    haystack match {
       case Nil => /* handle it */
       case needle::Nil => needle
       case front::needle::back => back.head
       case needle::back::Nil => back.head
    }
}

些細なケースでのみ機能させることができます。

これはパターンマッチングを使用して行うことができますか? リストのメソッドを使用して動作させることができることはわかっていますが、これは単なるおもちゃのプログラムです。

4

3 に答える 3

3
def findNext(needle : Int, haystack : List[Int]): Option[Int] = {
  @annotation.tailrec def loop(needle : Int, haystack : List[Int], trueHead: Int): Option[Int] =
    haystack match {
      case Nil => None
      case `needle` :: next :: _ => Some(next)
      case `needle` :: Nil => Some(trueHead)
      case _ :: tail => loop(needle, tail, trueHead)
    }
  haystack match {
    case Nil | _ :: Nil => None
    case _ => loop(needle, haystack, haystack.head)
  }
}

パターン マッチングのバック ティックについては、この回答を参照してください。

使用法:

scala> findNext(1,List(1,2,3))
res0: Option[Int] = Some(2)

scala> findNext(2,List(1,2,3))
res1: Option[Int] = Some(3)

scala> findNext(3,List(1,2,3))
res2: Option[Int] = Some(1)

scala> findNext(4,List(1,2,3))
res3: Option[Int] = None

scala> findNext(1,List(1,1))
res4: Option[Int] = Some(1)

scala> findNext(1,List(1))
res5: Option[Int] = None

scala> findNext(1,List())
res6: Option[Int] = None
于 2013-03-28T03:42:11.387 に答える
2

針が見つからない場合もありますので、Option[Int]こちらで返却するのがベストです。パターンマッチングだけを使用して、次の方法で解決できます。

@tailrec def findNext(needle: Int, haystack: List[Int]): Option[Int] = {
    haystack match {
      case Nil => None
      case front::next::back if front == needle => Some(next)
      case head::tail => findNext(needle, tail)
    }
  }

またはさらに簡単です:

  @tailrec def findNext(needle: Int, haystack : List[Int]): Option[Int] = {
    haystack match {
      case Nil => None
      case head::tail if head == needle => tail.headOption
      case head::tail => findNext(needle, tail)
    }
  }

上記の例とは異なり、干し草の山に一致するものが見つからない場合、これは None を返すことに注意してください。関数の結果は、次のようにデフォルトの回答と組み合わせることができます。

val haystack = List(1,2,3,4)
findNext(4, haystack) getOrElse haystack.head
于 2013-03-28T03:44:34.543 に答える
1

haystack最後の要素が条件needleの助けを借りて である場合、これは元の先頭に戻りifます。はfindNextR、最後の要素が である場合に保存された値を保持しますneedle

def findNext(needle: Int, haystack: List[Int]): Option[Int]  =  {
  @annotation.tailrec def findNextR(needle: Int, haystack: List[Int], savedHead: Int): Option[Int]  =  {
    haystack match{
      case Nil => None
      case head :: tail => if (head == needle && tail.isEmpty) Some(savedHead)
                                   else if (head == needle) Some(tail.head)
                                   else findNextR(needle, tail, savedHead)
    }
  }
 findNextR(needle, haystack, haystack.head)
}

scala> :load findNext.scala
Loading findNext.scala...
findNext: (needle: Int, haystack: List[Int])Option[Int]

scala> findNext(1, List(1,2,3))
res0: Option[Int] = Some(2)

scala> findNext(2, List(1,2,3))
res1: Option[Int] = Some(3)

scala> findNext(3, List(1,2,3))
res2: Option[Int] = Some(1)
于 2013-03-28T04:07:36.430 に答える