2015-05-02 77 views
2

所以目前,我寫了一個Clojure的代碼做一個多項式函數的梯形集成HackerRank.com: https://www.hackerrank.com/challenges/area-under-curves-and-volume-of-revolving-a-curv梯形積分不夠準確Clojure中

(defn abs[x] 
    (max x (- 0 x)) 
) 

(defn exp[x n] 
    (if (> n 0) 
    (* x (exp x (- n 1))) 
    1 
    ) 
) 

(defn fact[x] 
    (if (> x 0) 
    (* x (fact (- x 1))) 
    1) 
) 

(defn func[x lst1 lst2] 
    ((fn step [sum lst1 lst2] 
    (if (> (.size lst1) 0) 
     (step (+ sum (* (last lst1) (exp x (last lst2)))) (drop-last lst1) (drop-last lst2)) 
     sum 
     ) 
    ) 
    0 lst1 lst2 
    ) 
) 


(defn integrate[f a b] 
    (def h 0.001) 
    (def n (/ (abs (- b a)) h)) 
    ((fn step[i sum] 
    (if (< i n) 
     (step (+ i 1) (+ sum (f (+ (* i h) a)))) 
     (* h (+ (/(+ (f a) (f b)) 2) sum)) 
    ) 
    ) 0 0) 
) 


(defn volumeIntegral[f a b] 
    (defn area[r] 
    (* 3.14159265359 (* r r))) 

    (def h 0.001) 
    (def n (/ (abs (- b a)) h)) 
    ((fn step[i sum] 
    (if (< i n) 
     (step (+ i 1) (+ sum (area (f (+ (* i h) a))))) 
     (* h (+ (/ (+ (f a) (f b)) 2) sum)) 
     ) 
    ) 0 0) 
    ) 

(defn lineToVec[line_str] (clojure.string/split line_str #"\s+")) 
(defn strToDouble [x] (Double/parseDouble (apply str (filter #(Character/isDigit %) x)))) 

(defn readline[vec] 
    ((fn step[list vec] 
    (if (> (.size vec) 0) 
     (step (conj list (last vec)) (drop-last vec)) 
     list 
    ) 
    ) '() vec) 
) 


(integrate (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2) 
(volumeIntegral (fn [x] (func x '(1 2 3 4 5 6 7 8) '(-1 -2 -3 -4 1 2 3 4))) 1 2) 

但是,輸出我已經是:

107.38602491666647 
45611.95754801859 

雖然被認爲是圍繞:

101.4 
41193.0 

我的代碼通過了前兩個測試用例,但沒有成功通過其餘的測試。我認爲是因爲問題的準確性。我多次瀏覽了我的代碼,但看起來似乎無法讓它變得更好。我在這裏做錯了什麼?謝謝。

回答

3

您的exp函數不太正確 - 它不能正確處理負指數。可能最好只使用Math/pow

你可以做的是調整volumeIntegralh值,但爲了避免棧的問題,使用recur(它給你的尾遞歸),其他的事情,例如這裏有一個稍微修改後的版本:

(defn volume-integral [f a b] 
    (defn area[r] 
    (* Math/PI (* r r))) 
    (def h 0.000001) 
    (def n (/ (abs (- b a)) h)) 
    ((fn [i sum] 
    (if (not (< i n)) 
     (* h (+ (/ (+ (f a) (f b)) 2) sum)) 
     (recur (+ i 1) (+ sum (area (f (+ (* i h) a))))))) 
    0 0)) 

(我做了integral類似的東西)所有的一切,我是不是能夠很打到第二個數字,但是這應該讓你在正確的軌道上:

101.33517384995224 
41119.11576557253 
+0

謝謝!!我根本沒有意識到這一點。 – atmosphere506