我想知道是否有办法以更实用的方式处理while(n> 0)循环,我有一个小的Scala应用程序,它计算从1到N的范围内等于K的位数: 例如30和3将返回4 [3,13,23,30]
object NumKCount {
def main(args: Array[String]): Unit = {
println(countK(30,3))
}
def countKDigit(n:Int, k:Int):Int = {
var num = n
var count = 0
while (num > 10) {
val digit = num % 10
if (digit == k) {count += 1}
num = num / 10
}
if (num == k) {count += 1}
count
}
def countK(n:Int, k:Int):Int = {
1.to(n).foldLeft(0)((acc, x) => acc + countKDigit(x, k))
}
}
我正在寻找一种使用纯函数方法定义函数countKDigit的方法
答案 0 :(得分:2)
首先将数字n
扩展为数字序列
def digits(n: Int): Seq[Int] = {
if (n < 10) Seq(n)
else digits(n / 10) :+ n % 10
}
然后通过计算k
def countKDigit(n:Int, k:Int):Int = {
digits(n).count(_ == k)
}
或者您可以使用countKDigit
flatMap
def countK(n:Int, k:Int):Int = {
1.to(n).flatMap(digits).count(_ == k)
}
答案 1 :(得分:0)
假设K
总是1位数,您可以将n
转换为String
并使用collect
或filter
,如下所示(功能不多)你可以用Integer
)做的事情:
def countKDigit(n: Int, k: Int): Int = {
n.toString.collect({ case c if c.asDigit == k => true }).size
}
或
def countKDigit(n: Int, k: Int): Int = {
n.toString.filter(c => c.asDigit == 3).length
}
E.g。
scala> 343.toString.collect({ case c if c.asDigit == 3 => true }).size
res18: Int = 2
scala> 343.toString.filter(c => c.asDigit == 3).length
res22: Int = 2
答案 2 :(得分:0)
以下方法如何:
scala> val myInt = 346763
myInt: Int = 346763
scala> val target = 3
target: Int = 3
scala> val temp = List.tabulate(math.log10(myInt).toInt + 1)(x => math.pow(10, x).toInt)
temp: List[Int] = List(1, 10, 100, 1000, 10000, 100000)
scala> temp.map(x => myInt / x % 10)
res17: List[Int] = List(3, 6, 7, 6, 4, 3)
scala> temp.count(x => myInt / x % 10 == target)
res18: Int = 2
答案 3 :(得分:0)
计算数字序列中单个数字的出现次数。
def countK(n:Int, k:Int):Int = {
assert(k >= 0 && k <= 9)
1.to(n).mkString.count(_ == '0' + k)
}
如果您真的只想将countKDigit()
修改为功能更强大的设计,那么总会有递归。
def countKDigit(n:Int, k:Int, acc: Int = 0):Int =
if (n == 0) acc
else countKDigit(n/10, k, if (n%10 == k) acc+1 else acc)