scala求list长度

//右折叠 从最右端开始真正的计算
  def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = as match {
    case Nil => z
    case Cons(t, h) => f(t, foldRight(h, z)(f))
    case Cons(t, h) => foldLeft(h, f(t, z))((x, y) => f(y, x)) //使用foldLeft 来实现 foldRight
  }


//使用右折叠计算链表长度
  def length[A](l: List[A]): Int = l match {
    case Nil => 0
    case Cons(_, t) => foldRight(t, 1)((_, y) => y + 1)
    //参数对应 这里的下划线对应 t中的某一个元素  y对应1  这里的1是起始数据 后面会跟这进行变化

  }
  def length2[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+y)
  def length3[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+0)
  //这个方法 直接返回 因为在运行第一次后 可以直接进行f函数的表达式的运算 1+0  运算式里没有需要继续解决的 表达式 所以直接返回结果
  //因而不会进行后续的迭代 f(t, foldRight(h, z)(f)) 到第一步 就直接返回1+0了 没有后续的运算  进行递归的话 需要运算的表达式中还需要有
  //待处理的 运算式 而不是参数
  • 递归的发生条件是 把运算过程 带到自己要进行具体的执行过程中 如果执行过程中 不存在了需要解决的运算过程 那么直接返回结果 而不管参数如何

def length3[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+0)
这行代码 在执行 第一次的时候 如下

  f(t, foldRight(h, z)(f))=f( _ ,foldRight(_,0)f)=1+0
  • 如上 后面的执行过程中 已经没有要处理的运算过程 因而会直接返回结果 1
    需要变成下面这样
 f(t, foldRight(h, z)(f))=f( _ ,foldRight(_,0)f)=1+foldRight(_,0)
  • 这样 才会接着进行下去
  • 所以 1+0 要变为 1+y  才行

猜你喜欢

转载自blog.csdn.net/zhaoyu_nb/article/details/85839022