OCaml

2015-07-12 2 views
5

में एक int को उलटाना मैं खुद को ओकैमल पढ़ रहा हूं, और अभ्यास के लिए उपयोग किए जाने वाले मुख्य संसाधन कुछ समस्याएं हैं जो कॉर्नेल ने 3110 वर्ग से उपलब्ध कराई है। समस्याओं में से एक एक int को उल्टा करने के लिए एक फ़ंक्शन लिखना है (यानी: 1234 -> 4321, -1234 -> -4321, 2 -> 2, -10 -> -1 आदि)।OCaml

मैं एक काम कर समाधान है, लेकिन मैं चिंतित हैं कि यह वास्तव में मुहावरेदार OCaml नहीं है कर रहा हूँ:

let rev_int (i : int) : int = 
    let rec power cnt value = 
    if value/10 = 0 then cnt 
    else power (10 * cnt) (value/10) in 
    let rec aux pow temp value = 
    if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value/10) 
    else temp in 
    aux (power 1 i) 0 i 

यह जहाँ तक मैं बता सकता है सभी मामलों में ठीक से काम करता है, लेकिन यह सिर्फ गंभीरता से लगता है " un-oCaml "मेरे लिए, विशेष रूप से क्योंकि मैं दो आंतरिक-कार्यों के साथ दो बार int की लंबाई के माध्यम से चल रहा हूँ। तो मैं बस सोच रहा हूं कि ऐसा करने के लिए एक और "ओकैमल" तरीका है या नहीं।

let decompose_int i = 
    let r = i/10 in 
    i - (r * 10) , r 

इस समारोह मुझे पूर्णांक विघटित रूप में अगर मैं एक सूची थी अनुमति देता है:

+0

क्यों नहीं - स्ट्रिंग -> चार सरणी -> चार सरणी उलट>> स्ट्रिंग -> उलटा उलट? यह ओकैमल नहीं है लेकिन मैंने https://en.wikipedia.org/wiki/Lychrel_number के साथ खेलते समय एसएमएल/एनजे (इंपोड और विस्फोट का उपयोग करके ओकैम की कमी महसूस कर रहा है) में समान चीजें की हैं। सरल परिवर्तनों को एक साथ जोड़ना कार्यात्मक प्रोग्रामिंग में काफी मूर्खतापूर्ण है। इसमें डेटा पर एकाधिक पास लग सकते हैं, लेकिन भाषा सीखते समय "समयपूर्व अनुकूलन से बचें" अच्छी सलाह है। –

+4

मुझे आपके समाधान के बारे में कुछ भी अनियमित नहीं दिख रहा है। शायद कुछ और चालाक समाधान हैं, लेकिन यह एक अलग सवाल है। –

उत्तर

4

मैं कहूंगा कि निम्नलिखित मूर्खतापूर्ण है।

(* [rev x] returns such value [y] that its decimal representation 
    is a reverse of decimal representation of [x], e.g., 
    [rev 12345 = 54321] *) 
let rev n = 
    let rec loop acc n = 
    if n = 0 then acc 
    else loop (acc * 10 + n mod 10) (n/10) in 
    loop 0 n 

लेकिन के रूप में जेफ्री एक टिप्पणी में कहा, अपने समाधान काफी मुहावरेदार है, हालांकि नहीं सबसे अच्छा एक। मैं पैटर्न if/then/else को मिलान पसंद करते हैं के रूप में

let rev n = 
    let rec loop acc = function 
    | 0 -> acc 
    | n -> loop (acc * 10 + n mod 10) (n/10) in 
    loop 0 n 

:

Btw, मेरी खुद की शैली, इस तरह लिखने के लिए होगा। लेकिन यह मेरा व्यक्तिगत स्वाद का मामला है।

+0

धन्यवाद; यह मैंने जो कल्पना की थी उसके आधार पर था। अन्य उत्तरों के बारे में, शायद मुझे अपने पोस्ट में उल्लेख करना चाहिए था कि मैं string_of_int जैसे 'अंतर्निर्मित' फ़ंक्शंस का उपयोग करने से बचने की कोशिश कर रहा था। –

1

मैं तुम्हें यह करने का कोई रास्ता प्रस्ताव कर सकते हैं। उदाहरण के लिए 12344 और 123 में विघटित है। फिर हम इसे उलट देते हैं।

let rec rev_int i = match decompose_int i with 
    | x , 0 -> 10 , x 
    | h , t -> 
    let (m,r) = rev_int t in 
    (10 * m, h * m + r) 

विचार यहाँ 10, 100, 1000 वापस जाने के लिए है ... और इतने पर पता करने के लिए जहां पिछले अंक जगह।


क्या मैं यहाँ करना चाहते थे उन्हें इलाज के लिए के रूप में मैं, सूचियों का इलाज होगा decompose_int एक List.hd और List.tl बराबर किया जा रहा है।