2010-01-21 30 views
9

我試圖計算的位數Clojure中的一些數字如下:我得到的StackOverflowError甚至2個位數StackOverflow的同時計數位數

(defn num-digits [n] 
    (if (= 0 n) 
    0 
    (inc (num-digits (/ n 10))))) 
(println (num-digits 93)) 

但是如果我更換/時取消選中鴻溝然後它爲至少93但無論的技術適用於:

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 

首先,我想知道如何用Clojure進行分割C風格。每當我做(/ x y)我得到一個比率,而不是一個整數。有什麼辦法呢?

其次,有沒有一種方法可以將這個數字轉換爲一個數字向量並對其進行調用。

感謝,
阿賈伊摹

+2

我不知道'關於Clojure,但不應該有某種方法將數字轉換爲字符串,然後只是獲得字符串的長度?幾乎所有我能想到的語言都有這樣的功能。 – ewall 2010-01-21 18:47:38

+0

log10:https://stackoverflow.com/questions/27229987/can-i-know-how-many-digits-a-number-is-without-count-it – coredump 2016-02-17 22:13:15

回答

3

this page,您可以用Clojure使用quot執行整數除法:

(quot n 10) 
3

Clojure的嘗試 「做正確的事」 與數字運算和從未失去精度。所以當你的設備說17/10時,結果是17/10分(十七分之一)不是1.默認情況下,任何數字操作都不會丟失任何信息。在這樣的情況下,你可以明確地扔掉多餘的精度(quote x 10)或者你可以將結果轉換爲int (int (/ 17 10))

對於這裏的第二個問題是一個小黑客:

(count (str 257)) 

一個很好的方法來保持自在Clojure中遞歸堆棧的方法是使用其他高階函數而不是遞歸。

(count (take-while pos? (iterate #(quot % 10) 257)))) 
4

Clojure沒有tail-call優化。您必須使用recur特殊形式。

E.g.:

(defn num-digits [n] 
    (loop [n n 
     cnt 0] 
    (if (= 0 n) 
     cnt 
     (recur (quot n 10) (inc cnt))))) 

但在回答你的第二個問題:是的,這是怎麼了:

(defn num-digits [n] (count (str n))) 
+0

在原始代碼中,調用甚至不在尾部位置。所以這段代碼也會在其他語言中失敗。 – kotarak 2010-01-22 10:21:00

8

這就是爲什麼你有一個問題:

user> (take 10 (iterate #(/ % 10) 10923)) 

(10923 10923/10 10923/100 10923/1000 10923/10000 10923/100000 10923/1000000 10923/10000000 10923/100000000 10923/1000000000) 

這是修復:

user> (take 10 (iterate #(quot % 10) 10923)) 

(10923 1092 109 10 1 0 0 0 0 0) 

這是表達式y ou're尋找:

user> (count (take-while #(not (zero? %)) (iterate #(quot % 10) 10923))) 
5 

這是一種欺騙行爲:

user> (count (str 10923)) 
5 

這是你想要寫的函數(但小心,就會棧對於大量溢出):

user> (defn num-digits [n] 
     (if (= 0 n) 
      0 
      (inc (num-digits (quot n 10))))) 

#'user/num-digits 
user> (num-digits 10923) 
5 

然而,準備好迎接挑戰:

user> (num-digits 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000) 

158 

這個版本的功能將不吹堆棧:

user> (defn num-digits-tail-recursion 
     ([n count] 
      (if (= 0 n) 
      count 
      (recur (quot n 10) (inc count)))) 
     ([n] (num-digits-tail-recursion n 0))) 
#'user/num-digits-tail-recursion 
user> (num-digits-tail-recursion 10923) 
5 

所有版本都以自己的方式有趣。好問題!