Scala递归地对给定谓词的元素计数

Scala递归地对给定谓词的元素计数,scala,recursion,Scala,Recursion,我有一个迭代函数,它计算列表中布尔值的数量 def countBoolIter[A](test: A=>Boolean, a: List[A]) = { var count = 0 for(elem <- a){ if(test(elem)) count += 1 } count } 调用函数如下所示: countBoolIter(isBool, List(1, true, 3, true, false, "hi")) // Outp

我有一个迭代函数,它计算列表中布尔值的数量

def countBoolIter[A](test: A=>Boolean, a: List[A]) = {
    var count = 0
    for(elem <- a){
        if(test(elem)) count += 1
    }
    count
}
调用函数如下所示:

countBoolIter(isBool, List(1, true, 3, true, false, "hi"))
// Output: 3
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
    case Nil => acc
    case h :: t if(test(h)) => countBoolRec(test, a, acc+1)
    case h :: t => countBoolRec(test, a, acc)
}
现在,我尝试将其转换为如下尾部递归函数:

countBoolIter(isBool, List(1, true, 3, true, false, "hi"))
// Output: 3
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
    case Nil => acc
    case h :: t if(test(h)) => countBoolRec(test, a, acc+1)
    case h :: t => countBoolRec(test, a, acc)
}
然而,我得到了一个运行时错误,因为函数没有返回任何东西;不会抛出任何错误。我认为它被困在一个无限循环中,这就是为什么没有返回任何东西


问题:我应该如何修复尝试的递归实现?

函数countBoolRec中存在错误:

    @tailrec
    def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
        case Nil => acc
        case h :: t if(test(h)) => countBoolRec(test, t, acc+1)
        case h :: t => countBoolRec(test, t, acc)
    }
在递归调用中,使用t作为参数,再次使用no作为a。如果不是,基本上,你是在一个无限循环中


另外,最好使用@tailrec注释,以确保实现是“tail recursive”。

函数countBoolRec中有错误:

    @tailrec
    def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
        case Nil => acc
        case h :: t if(test(h)) => countBoolRec(test, t, acc+1)
        case h :: t => countBoolRec(test, t, acc)
    }
在递归调用中,使用t作为参数,再次使用no作为a。如果不是,基本上,你是在一个无限循环中


另外,最好使用@tailrec注释来确保实现是“尾部递归的”。

您使用与输入相同的列表重复递归

考虑a.head通过测试的情况:

countBoolRec(测试,a,0) countBoolRec(测试,a,1) countBoolRec(测试,a,2) ... 等等

@scala.annotation.tailrec // Not that your original code wasn't tail-recursive, but it's a generally good practice to mark code that isn't tail recursive with this annotation
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
  case Nil => acc
  case h :: t if (test(h)) => countBoolRec(test, t, acc + 1)
  case h :: t => countBoolRec(test, t, acc)
}
尽管你也可以写:

(0 /: a) { (acc, v) => acc + (if (test(v)) 1 else 0) }

您重复使用与输入相同的列表进行递归

考虑a.head通过测试的情况:

countBoolRec(测试,a,0) countBoolRec(测试,a,1) countBoolRec(测试,a,2) ... 等等

@scala.annotation.tailrec // Not that your original code wasn't tail-recursive, but it's a generally good practice to mark code that isn't tail recursive with this annotation
def countBoolRec[A](test: A=>Boolean, a: List[A], acc: Int = 0): Int = a match {
  case Nil => acc
  case h :: t if (test(h)) => countBoolRec(test, t, acc + 1)
  case h :: t => countBoolRec(test, t, acc)
}
尽管你也可以写:

(0 /: a) { (acc, v) => acc + (if (test(v)) 1 else 0) }

笑话:如果你是一名密码学家,第二个选项是可以的。笑话:如果你是一名密码学家,第二个选项是可以的。“我应该如何修复我尝试的递归实现?”这是一个通过调试程序逐步解决的问题。现在人们不使用调试器吗?离开我的草坪。“我应该如何修复我尝试的递归实现?”这是一个可以通过调试程序轻松解决的问题。现在人们不使用调试器吗?离开我的草坪。