zoukankan      html  css  js  c++  java
  • Stream

    package stream
    
    import Stream._
    sealed trait Stream[+A] {
    
      def toList0: List[A] = this match {
        case Empty      => Nil
        case Cons(h, t) => h() :: t().toList0
      }
    
      def toList: List[A] = {
        @annotation.tailrec
        def loop(s: Stream[A], acc: List[A]): List[A] = s match {
          case Cons(h, t) => loop(t(), h() :: acc)
          case _          => acc
        }
        loop(this, Nil).reverse
      }
    
      def take(n: Int): Stream[A] = this match {
        case Cons(h, t) if n > 1  => cons(h(), t().take(n - 1))
        case Cons(h, _) if n == 1 => cons(h(), empty)
        case _                    => empty
      }
    
      @annotation.tailrec
      final def drop(n: Int): Stream[A] = this match {
        case Cons(_, t) if n > 0 => t().drop(n - 1)
        case _                   => this
      }
    
      def takeWhile(p: A => Boolean): Stream[A] = this match {
        case Cons(h, t) if (p(h())) => cons(h(), t().takeWhile(p))
        case _                      => empty
      }
    
      def foldRight[B](z: => B)(f: (A, => B) => B): B =
        this match {
          case Cons(h, t) => f(h(), t().foldRight(z)(f))
          case _          => z
        }
    
      def exists(p: A => Boolean): Boolean = foldRight(false)((a, b) => p(a) || b)
    
      def forAll(p: A => Boolean): Boolean = foldRight(true)((a, b) => p(a) && b)
    
      def takeWhileByFoldRight(p: A => Boolean): Stream[A] = foldRight(empty[A])((a, b) => if (p(a)) cons(a, b) else b)
    
      def headOption: Option[A] = foldRight(None: Option[A])((a, b) => Some(a))
    
      def map[B](f: A => B): Stream[B] = foldRight(empty[B])((a, b) => cons(f(a), b))
    
      def filter(f: A => Boolean): Stream[A] = foldRight(empty[A])((a, b) => if (f(a)) cons(a, b) else b)
    
      def append[B >: A](s: => Stream[B]): Stream[B] = foldRight(s)((a, b) => cons(a, b))
    
      def flatMap[B](f: A => Stream[B]): Stream[B] = foldRight(empty[B])((a, b) => f(a).append(b))
    
      def mapByUnfold[B](f: A => B): Stream[B] = unfold(this) {
        case Cons(h, t) => Some(f(h()), t())
        case _          => None
      }
    
      def takeByUnfold(n: Int): Stream[A] = unfold((n, this)) {
        case (i, Cons(h, t)) if i > 0 => Some((h(), (i - 1, t())))
        case _                        => None
      }
    
      def takeWhileByUnfold(f: A => Boolean): Stream[A] = unfold(this) {
        case Cons(h, t) if (f(h())) => Some((h(), t()))
        case _                      => None
      }
    
      def zipWith[B, C](s: Stream[B])(f: (A, B) => C): Stream[C] = unfold(this, s) {
        case (Cons(h1, t1), Cons(h2, t2)) => Some((f(h1(), h2()), (t1(), t2())))
        case _                            => None
      }
    
      def zipAll[B](s: Stream[B]): Stream[(Option[A], Option[B])] = unfold(this, s) {
        case (Empty, Empty)               => None
        case (Empty, Cons(h2, t2))        => Some((None, Some(h2())), (empty, t2()))
        case (Cons(h1, t1), Empty)        => Some((Some(h1()), None), (t1(), empty))
        case (Cons(h1, t1), Cons(h2, t2)) => Some((Some(h1()), Some(h2())), (t1(), t2()))
      }
    
      def tails: Stream[Stream[A]] =
        unfold(this) {
          case Empty => None
          case s     => Some((s, s drop 1))
        } append Stream(empty)
    
      def startsWith[A](s: Stream[A]): Boolean =
        zipAll(s).takeWhile(!_._2.isEmpty) forAll {
          case (h, h2) => h == h2
        }
    
      def hasSubsequence[A](s: Stream[A]): Boolean = tails exists (_ startsWith s)
    
      def scanRight[B](z: B)(f: (A, => B) => B): Stream[B] =
        foldRight((z, Stream(z)))((a, p0) => {
          lazy val p1 = p0
          val b2 = f(a, p1._1)
          (b2, cons(b2, p1._2))
        })._2
    }
    
    case object Empty extends Stream[Nothing]
    case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
    
    object Stream {
    
      def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
        lazy val head = hd
        lazy val tail = tl
        Cons(() => head, () => tail)
      }
    
      def empty[A]: Stream[A] = Empty
    
      def apply[A](as: A*): Stream[A] = if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
    
      def constant[A](a: A): Stream[A] = Stream.cons(a, constant(a))
    
      def from(n: Int): Stream[Int] = Stream.cons(n, from(n + 1))
    
      def fibs(n: Int, n1: Int): Stream[Int] = Stream.cons(n, fibs(n1, n + n1))
    
      def unfold[A, S](z: S)(f: S => Option[(A, S)]): Stream[A] = f(z) match {
        case Some((a, s)) => cons(a, unfold(s)(f))
        case _            => empty
      }
    
      def fromByUnfold(n: Int): Stream[Int] = unfold(n)(n => Some(n, n + 1))
    
      def constantByUnfold[A](a: A): Stream[A] = unfold(a)(a => Some(a, a))
    
      def onesByUnfold: Stream[Int] = unfold(1)(_ => Some(1, 1))
    }
    
    object Run {
    
      def main(args: Array[String]): Unit = {
    
        val s = Stream(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
        println(s.toList0)
        println(s.toList)
    
        println(s.take(3))
        println(s.take(3).toList)
    
        println(s.drop(3))
        println(s.drop(3).toList)
    
        println(s.takeWhile(x => x < 5))
        println(s.takeWhile(x => x < 5).toList)
    
        println(s.forAll(_ % 1 == 0))
        println(s.forAll(_ % 2 == 0))
    
        println(s.takeWhileByFoldRight(_ % 2 == 0))
        println(s.takeWhileByFoldRight(_ % 2 == 0).toList)
    
        println(s.headOption)
        println(Stream().headOption)
    
        println(s.map(_ + 1))
        println(s.map(_ + 1).toList)
    
        println(s.filter(_ % 2 == 0))
        println(s.filter(_ % 2 == 0).toList)
    
        println(s.append(Stream(11, 12, 13, 14)))
        println(s.append(Stream(11, 12, 13, 14)).toList)
    
        println(s.flatMap(x => Stream(x + 100)))
        println(s.flatMap(x => Stream(x + 100)).toList)
    
        println(Stream.constant(12).take(10))
        println(Stream.constant(12).take(10).toList)
    
        println(Stream.from(12).take(10))
        println(Stream.from(12).take(10).toList)
    
        println(Stream.fibs(0, 1).take(10))
        println(Stream.fibs(0, 1).take(10).toList)
    
        println(Stream.unfold(0)(z => Some((z, z + 1))).take(10))
        println(Stream.unfold(0)(z => Some((z, z + 1))).take(10).toList)
    
        println(Stream.fromByUnfold(12).take(10))
        println(Stream.fromByUnfold(12).take(10).toList)
    
        println(Stream.constantByUnfold(12).take(10))
        println(Stream.constantByUnfold(12).take(10).toList)
    
        println(Stream.onesByUnfold.take(10))
        println(Stream.onesByUnfold.take(10).toList)
    
        println(s.mapByUnfold(_ + 1))
        println(s.mapByUnfold(_ + 1).toList)
    
        println(s.takeByUnfold(3))
        println(s.takeByUnfold(3).toList)
    
        println(s.takeWhileByUnfold(x => x < 5))
        println(s.takeWhileByUnfold(x => x < 5).toList)
    
        println(s.zipWith(Stream(11, 12, 13, 14, 15))(_ + _))
        println(s.zipWith(Stream(11, 12, 13, 14, 15))(_ + _).toList)
    
        println(s.zipAll(Stream(11, 12, 13, 14, 15)))
        println(s.zipAll(Stream(11, 12, 13, 14, 15)).toList)
    
        println(s.tails)
        println(s.tails.toList.map(_.toList))
    
        println(s.startsWith(Stream(1, 2, 3, 4, 5)))
        println(s.startsWith(Stream(1, 12, 3, 4, 5)))
    
        println(s.hasSubsequence(Stream(3, 4, 5)))
        println(s.hasSubsequence(Stream(3, 44, 5)))
    
        println(Stream(1, 2, 3).scanRight(0)(_ + _))
        println(Stream(1, 2, 3).scanRight(0)(_ + _).toList)
      }
    
    }
    List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    Cons(<function0>,<function0>)
    List(1, 2, 3)
    Cons(<function0>,<function0>)
    List(4, 5, 6, 7, 8, 9)
    Cons(<function0>,<function0>)
    List(1, 2, 3, 4)
    true
    false
    Cons(<function0>,<function0>)
    List(2, 4, 6, 8)
    Some(1)
    None
    Cons(<function0>,<function0>)
    List(2, 3, 4, 5, 6, 7, 8, 9, 10)
    Cons(<function0>,<function0>)
    List(2, 4, 6, 8)
    Cons(<function0>,<function0>)
    List(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14)
    Cons(<function0>,<function0>)
    List(101, 102, 103, 104, 105, 106, 107, 108, 109)
    Cons(<function0>,<function0>)
    List(12, 12, 12, 12, 12, 12, 12, 12, 12, 12)
    Cons(<function0>,<function0>)
    List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
    Cons(<function0>,<function0>)
    List(0, 1, 1, 2, 3, 5, 8, 13, 21, 34)
    Cons(<function0>,<function0>)
    List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    Cons(<function0>,<function0>)
    List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
    Cons(<function0>,<function0>)
    List(12, 12, 12, 12, 12, 12, 12, 12, 12, 12)
    Cons(<function0>,<function0>)
    List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    Cons(<function0>,<function0>)
    List(2, 3, 4, 5, 6, 7, 8, 9, 10)
    Cons(<function0>,<function0>)
    List(1, 2, 3)
    Cons(<function0>,<function0>)
    List(1, 2, 3, 4)
    Cons(<function0>,<function0>)
    List(12, 14, 16, 18, 20)
    Cons(<function0>,<function0>)
    List((Some(1),Some(11)), (Some(2),Some(12)), (Some(3),Some(13)), (Some(4),Some(14)), (Some(5),Some(15)), (Some(6),None), (Some(7),None), (Some(8),None), (Some(9),None))
    Cons(<function0>,<function0>)
    List(List(1, 2, 3, 4, 5, 6, 7, 8, 9), List(2, 3, 4, 5, 6, 7, 8, 9), List(3, 4, 5, 6, 7, 8, 9), List(4, 5, 6, 7, 8, 9), List(5, 6, 7, 8, 9), List(6, 7, 8, 9), List(7, 8, 9), List(8, 9), List(9), List())
    true
    false
    true
    false
    Cons(<function0>,<function0>)
    List(6, 5, 3, 0)
  • 相关阅读:
    使用vue做项目时,刷新页面,原本应该隐藏的东西闪一下
    input type="file" 上传文件的一些使用
    vue强制重新渲染
    元素focus页面不滚动不定位的JS处理
    js使用案例
    js使用setInterval简单实现一个时钟
    js日期封装方法
    scss简单使用总结
    JavaScript的内置对象(Global对象)
    JavaScript—Date对象详情
  • 原文地址:https://www.cnblogs.com/JonkeyGuan/p/5448081.html
Copyright © 2011-2022 走看看