2011-08-14 16 views
8

मैं a programming contest और one of the problems में भाग ले रहा हूं 'इनपुट डेटा में दशमलव प्रारूप में एक आंशिक संख्या शामिल है: 0.75 एक उदाहरण है।हास्केल में तर्कसंगत में दशमलव अंश को कैसे पार्स करें?

Double में पार्सिंग छोटा है (मैं इसके लिए read का उपयोग कर सकता हूं), लेकिन सटीकता का नुकसान दर्दनाक है। Double तुलना (मुझे नहीं था) के साथ बहुत सावधान रहने की आवश्यकता है, जो अनावश्यक लगता है क्योंकि किसी के पास Rational डेटा प्रकार हैस्केल में है।

इसका उपयोग करने का प्रयास करते समय, मैंने पाया है कि readRational को निम्नलिखित प्रारूप में एक स्ट्रिंग प्रदान करनी है: numerator % denominator, जो कि, जाहिर है, मेरे पास नहीं है।

तो, सवाल यह है:

Rational में एक अंश के एक दशमलव प्रतिनिधित्व पार्स करने के लिए सबसे आसान तरीका क्या है?

बाह्य निर्भरताओं की संख्या को भी ध्यान में रखा जाना चाहिए, क्योंकि मैं ऑनलाइन जज में अतिरिक्त पुस्तकालय स्थापित नहीं कर सकता।

उत्तर

15

समारोह आप चाहते हैं Numeric.readFloat है:

Numeric Data.Ratio> fst . head $ readFloat "0.75" :: Rational 
3 % 4 
+0

धन्यवाद! यह काम। – Rotsor

+6

यदि आप नकारात्मक संख्याएं पढ़ने में सक्षम होना चाहते हैं तो आप 'readSigned' जोड़ना चाहेंगे:' fst। हेड $ readSigned readFloat "-3.14" :: तर्कसंगत ' – newacct

3

कैसे निम्नलिखित (GHCi सत्र) के बारे में:

> :m + Data.Ratio 
> approxRational (read "0.1" :: Double) 0.01 
1 % 10 
कोर्स आप अपने एप्सिलॉन उचित रूप से लेने के लिए है

+0

यह एक अच्छा विचार है! मुझे लगता है कि ज्यादातर परिस्थितियों में 'toRational' के बजाय इसका उपयोग किया जाना चाहिए! – Rotsor

+0

दुर्भाग्यवश, ईपीएसलॉन की पसंद यहां स्पष्ट नहीं है। उदाहरण के लिए, 'अनुमानित 0.9 99 0.0001'' 9 0 9% 9 10' है, जो मैं नहीं चाहता हूं। इस मामले में उपयोग करने के लिए उचित ईपीएसलॉन '0.000001' (परिशुद्धता वर्ग?) – Rotsor

1

शायद आप यह अपने आप को लागू करने के लिए प्रतियोगिता में अतिरिक्त अंक पाने चाहते हैं:

import Data.Ratio ((%)) 

readRational :: String -> Rational 
readRational input = read intPart % 1 + read fracPart % (10^length fracPart) 
    where (intPart, fromDot) = span (/='.') input 
     fracPart   = if null fromDot then "0" else tail fromDot 
+0

मुझे ऐसा नहीं लगता है। ऐसी प्रतियोगिताओं में केवल जमा करने का समय और शुद्धता मायने रखती है। अच्छा समाधान अभी भी, एक आपात स्थिति में कोड के लिए पर्याप्त छोटा है। – Rotsor

संबंधित मुद्दे