मैं क्लोजर में एक्सप्रेशन कैसे कर सकता हूं? अभी के लिए मुझे केवल पूर्णांक घातांक की आवश्यकता है, लेकिन प्रश्न अंशों के लिए भी जाता है।
मैं क्लोजर में एक्सप्रेशन कैसे कर सकता हूं? अभी के लिए मुझे केवल पूर्णांक घातांक की आवश्यकता है, लेकिन प्रश्न अंशों के लिए भी जाता है।
जवाबों:
क्लासिक पुनरावर्तन (इसे देखें, यह स्टैक को उड़ा देता है)
(defn exp [x n]
(if (zero? n) 1
(* x (exp x (dec n)))))
पूंछ की पुनरावृत्ति
(defn exp [x n]
(loop [acc 1 n n]
(if (zero? n) acc
(recur (* x acc) (dec n)))))
कार्यात्मक
(defn exp [x n]
(reduce * (repeat n x)))
डरपोक (स्टैक भी उड़ाता है, लेकिन इतनी आसानी से नहीं)
(defn exp-s [x n]
(let [square (fn[x] (* x x))]
(cond (zero? n) 1
(even? n) (square (exp-s x (/ n 2)))
:else (* x (exp-s x (dec n))))))
पुस्तकालय
(require 'clojure.contrib.math)
क्लोजर में एक शक्ति फ़ंक्शन होता है जो अच्छी तरह से काम करता है: मैं जावा इंटरॉप के माध्यम से जाने के बजाय इसका उपयोग करने की सलाह दूंगा क्योंकि यह सभी क्लोजर मनमाना-सटीक संख्या प्रकारों को सही ढंग से संभालता है। यह नामस्थान clojure.math.numeric-Tower में है ।
यह कहा जाता है expt
के लिए घातांक के बजाय power
या pow
जो शायद यही कारण है यह थोड़ा मुश्किल लगता करने के लिए है ... वैसे भी यहाँ एक छोटा सा उदाहरण है (ध्यान दें कि use
काम करता है लेकिन बेहतर इस्तेमाल require
):
(require '[clojure.math.numeric-tower :as math :refer [expt]]) ; as of Clojure 1.3
;; (use 'clojure.contrib.math) ; before Clojure 1.3
(expt 2 200)
=> 1606938044258990275541962092341162602522202993782792835301376
org.clojure.math.numeric-tower
क्लोजर नेमस्पेस को clojure.math.numeric-tower
सुलभ बनाने के लिए आपको सबसे पहले जावा पैकेज स्थापित करना होगा !
कमांड लाइन पर:
$ lein new my-example-project
$ cd lein new my-example-project
फिर निर्भरता वेक्टर में संपादित करें project.clj
और जोड़ें [org.clojure/math.numeric-tower "0.0.4"]
।
लेइन आरईपीएल शुरू करें (क्लोजर आरईपीएल नहीं)
$ lein repl
अभी:
(require '[clojure.math.numeric-tower :as math])
(math/expt 4 2)
;=> 16
या
(require '[clojure.math.numeric-tower :as math :refer [expt]])
(expt 4 2)
;=> 16
आप जावा Math.pow
या BigInteger.pow
विधियों का उपयोग कर सकते हैं :
(Math/pow base exponent)
(.pow (bigint base) exponent)
Math/pow
अधिक जटिल है math-pow
या जो भी नाम होगा अगर वहाँ एक क्लोजर बराबर था। यदि पहले से ही एक सरल जावा विधि है जो आप चाहते हैं, तो क्लोजर में कार्यक्षमता को फिर से बनाने का कोई कारण नहीं है। जावा इंटरॉप स्वाभाविक रूप से हानिकारक नहीं है।
जब यह प्रश्न मूल रूप से पूछा गया था, तो clojure.contrib.math / expt ऐसा करने के लिए आधिकारिक पुस्तकालय कार्य था। तब से, यह clojure.math.numeric-Tower में चला गया है
user=> (.pow (BigInteger. "2") 10)
1024
user=> (.pow (BigInteger. "2") 100)
1267650600228229401496703205376
(.pow 2M 100)
(Math/pow Math/E x)
लिए ट्रिक ( Math/E
आपकी पसंद के आधार के साथ प्रतिस्थापित ) करता है।
यदि आपको वास्तव में एक फ़ंक्शन की आवश्यकता है और एक विधि की नहीं, तो आप इसे बस लपेट सकते हैं:
(defn pow [b e] (Math/pow b e))
और इस फंक्शन में आप इसे int
या इसी तरह का कास्ट कर सकते हैं । फ़ंक्शंस अक्सर अधिक उपयोगी होते हैं जो विधियाँ क्योंकि आप उन्हें अन्य कार्यों के लिए मापदंडों के रूप में पारित कर सकते हैं - इस मामले map
में मेरे दिमाग में आता है।
यदि आपको वास्तव में जावा इंटरॉप से बचने की आवश्यकता है, तो आप अपना स्वयं का पावर फ़ंक्शन लिख सकते हैं। उदाहरण के लिए, यह एक सरल कार्य है:
(defn pow [n p] (let [result (apply * (take (abs p) (cycle [n])))]
(if (neg? p) (/ 1 result) result)))
यह पूर्णांक घातांक (यानी कोई जड़ नहीं) के लिए शक्ति की गणना करता है।
इसके अलावा, यदि आप बड़ी संख्या के साथ काम कर रहे हैं, तो आप इसके BigInteger
बजाय उपयोग करना चाह सकते हैं int
।
और यदि आप बहुत बड़ी संख्या के साथ काम कर रहे हैं , तो आप उन्हें अंकों की सूची के रूप में व्यक्त करना चाहते हैं, और अपने स्वयं के अंकगणितीय कार्यों को उन पर स्ट्रीम करने के लिए लिख सकते हैं क्योंकि वे परिणाम की गणना करते हैं और परिणाम को किसी अन्य स्ट्रीम में आउटपुट करते हैं।
मुझे लगता है कि यह भी काम करेगा:
(defn expt [x pow] (apply * (repeat pow x)))
का उपयोग करें clojure.math.numeric-tower
, पूर्व में clojure.contrib.math
।
(ns user
(:require [clojure.math.numeric-tower :as m]))
(defn- sqr
"Uses the numeric tower expt to square a number"
[x]
(m/expt x 2))
पूंछ पुनरावृत्ति और नकारात्मक प्रतिपादक का समर्थन करने के साथ "डरपोक" विधि का कार्यान्वयन:
(defn exp
"exponent of x^n (int n only), with tail recursion and O(logn)"
[x n]
(if (< n 0)
(/ 1 (exp x (- n)))
(loop [acc 1
base x
pow n]
(if (= pow 0)
acc
(if (even? pow)
(recur acc (* base base) (/ pow 2))
(recur (* acc base) base (dec pow)))))))
कम करने के लिए एक सरल वन-लाइनर:
(defn pow [a b] (reduce * 1 (repeat b a)))
प्रयत्न
(defn pow [x n]
(loop [x x n n r 1]
(cond
(= n 0) r
(even? n) (recur (* x x) (/ n 2) r)
:else (recur x (dec n) (* r x)))))
एक पूंछ-पुनरावर्ती हे (लॉग एन) समाधान के लिए, यदि आप इसे स्वयं लागू करना चाहते हैं (केवल सकारात्मक पूर्णांक का समर्थन करता है)। जाहिर है, बेहतर समाधान यह है कि पुस्तकालय कार्यों का उपयोग करें जो दूसरों ने इंगित किए हैं।
कैसे के बारे में clojure.contrib.genric.math-functions
Clojure.contrib.generic.math-functions लाइब्रेरी में एक पॉव फंक्शन है। यह Math.pow के लिए एक मैक्रो है और जावा गणित फ़ंक्शन को कॉल करने के "क्लोजुरिश" तरीके से अधिक है।