2010-01-24 9 views
5

मैं हास्केल में एक फ़ंक्शन कैसे लिख सकता हूं, जो प्रारूप a1a2a3 में इनपुट स्ट्रिंग लेता है और a1a2a2a3a3a3 में फैलता है। उदाहरण के लिए इनपुट स्ट्रिंग "कोड" को "coodddeeee"सीखना हास्केल: स्ट्रिंग मैनिपुलेशन प्रश्न

+0

कोड आप अब तक इस को हल करने के लिए लिखा है कृपया पोस्ट के साथ पागल जाने के लिए चाहते हैं। अन्यथा लोगों को संदेह हो सकता है कि यह होमवर्क है। –

+0

मैं आपको आश्वासन देता हूं, यह होमवर्क नहीं है :) मैं हास्केल पुस्तक में excersises के माध्यम से काम कर रहा था और मेरे दिमाग बस इस पर ठंडा हो गया। मुझे इस बिंदु पर पता है कि, मुझे ++ ऑपरेटर का उपयोग करने की आवश्यकता होगी, किसी प्रकार का सरणी हेरफेर और संभावित लंबाई लंबाई –

उत्तर

9

शायद बहुत अक्षम :)

f :: Int -> [Char] -> [Char] 
f _ [] = [] 
f n (c:s) = (replicate n c) ++ (f (n+1) s) 

g :: [Char] -> [Char] 
g s = f 1 s 

*Main> g "code" 
"coodddeeee" 
+5

एफवाईआई: जुड़ाव कुछ भी की तुलना में अधिक कसकर बांधता है, लेकिन, इसलिए आप कुछ अतिव्यापी परावर्तक कोष्ठक हटा सकते हैं। एफ एन (सी: एस) = प्रतिकृति एन सी ++ एफ (एन + 1) एस –

19

में विस्तारित किया जाएगा, तो आप nth वर्ण n बार बार-बार चाहते हैं।

f :: String -> String 
f x = concatMap g (zip x [1..]) 
    where 
     g (x,y) = replicate y x 

मुझे यकीन है कि ऐसा करने का एक आसान तरीका है।

स्पष्टीकरण: सबसे पहले हम स्ट्रिंग प्राप्त करते हैं और इसे सूची में (1 से शुरू) में जोड़ते हैं। यह वही ज़िप करता है:

Prelude> zip "code" [1..] 
[('c',1),('o',2),('d',3),('e',4)] 

अब समारोह g (x,y) जो प्रतिकृति जो कुछ भी आप y बार चाहते दोहराने समारोह का उपयोग करता है। तो हम एक्स, वाई बार दोहराना।

Prelude> map g $ zip "code" [1..] 
["c","oo","ddd","eeee"] 

आप स्ट्रिंग की एक सूची है, तो आप उन्हें एक साथ concat का उपयोग कर जोड़ सकते हैं:

Prelude> g ('z',4) 
"zzzz" 

हम उत्पादन सूची पर इस समारोह के नक्शे यदि आप परिणाम मिलता है। concatMap फ़ंक्शन g फ़ंक्शन और संख्या की प्रत्येक जोड़ी पर लागू होता है और फिर स्ट्रिंग को अंतिम परिणाम में जोड़ता है।

Prelude> concat $ map g $ zip "code" [1..] 
"coodddeeee" 

असल: concat $ map g ->concatMap g

संपादित करें: अब यह काम करता है, यह भी एक पंक्ति thusly में किया जा सकता:

f x = concatMap (\(a,b)->replicate b a) $ zip x [1..] 

आउटपुट:

Prelude> f "lambda" 
"laammmbbbbdddddaaaaaa" 
+0

जोनोनो का उपयोग करें ... क्या आप उस उत्तर को समझा सकते हैं, जैसा कि शुरुआती चरणों में है सीखना हैकेल, उपरोक्त उत्तर सिर्फ मुझे समझ में नहीं आता है। –

+0

स्पष्टीकरण के लिए संपादन देखें –

+2

मैं 'जी' को 'uncurry' से बदल दूंगा। फ्लिप दोहराना '। वही बात है, लेकिन मानक हास्केल पुस्तकालय कार्यों का उपयोग करता है। –

15
import Control.Monad 
f = zip [1..] >=> uncurry replicate 

पैदावार

Main> f "code" 
"coodddeeee" 
+1

अच्छा! मेरे जैसे लोगों के लिए, जो ऑपरेटर के प्रकार को नहीं जानते: "मोनैड की बाएं से दाएं क्लेस्ली संरचना: '(> =>) :: मोनाड एम => (ए -> एमबी) -> (बी -> एमसी) -> (ए -> एमसी) '" –

1
Prelude> let l = "code" in concat $ [take y $ repeat (last $ take y l) | y <- [1..length l]] 
"coodddeeee" 
4

क्यों लोगों सूची comprehensions नफरत करते हैं?

Prelude> let f s = concat [ replicate x y | (x,y) <- zip [1..] s] 
Prelude> f "code" 
"coodddeeee" 

या आप एक्सटेंशन

Prelude> :set -XParallelListComp 
Prelude> let f s = concat [ replicate x y | x <- [1..] | y <- s] 
Prelude> f "code" 
"coodddeeee" 
संबंधित मुद्दे