2017-06-09 60 views
2

我想知道是否有一種方式來處理一個更有效的方式(n> 0)循環,我有一個小的Scala應用程序,計數等於K從1到N的範圍內: 例如30和3將返回4 [3,13,23,30]scala如何減少,而n> 0

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使用純粹的功能的方法

回答

1

一是擴大數量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) 
} 

出現減少的順序或者你可以通過使用flatMap

避免 countKDigit完全
def countK(n:Int, k:Int):Int = { 
    1.to(n).flatMap(digits).count(_ == k) 
} 
0

假設K始終爲1個位數,你可以轉換到nString使用collectfilter像下面(有沒有你可以用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 
} 

例如

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 
+1

你可以用count(_。asDigit == k)替換'filter(c => c.asDigit == k).length'' –

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 
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)