Haskell'de, a1a2a3 biçiminde bir girdi dizesi alan ve a1a2a2a3a3a3'e genişleyen bir işlevi nasıl yazabilirim. Örneğin, giriş dizgisi "kod", "coodddeeee"Öğrenme Haskell: String manipülasyon sorusu
cevap
Muhtemelen çok verimsiz :)
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"
FYI: juxtaposition herşeyden daha sıkı bağlar ama @, Birkaç aşırı paranoyak parantezi kaldırabilirsiniz. f n (c: s) = çoğaltma n C++ f (n + 1) s –
'a genişletilecektir. Böylece karakterinin n
kez tekrarlanmasını istiyorsunuz.
f :: String -> String
f x = concatMap g (zip x [1..])
where
g (x,y) = replicate y x
Bunun için daha kolay bir yol olduğundan eminim.
Açıklama: Önce dizeyi alıp listedeki yeriyle eşleştirelim (1'den başlayarak). Bu ne fermuar geçerli:
Prelude> zip "code" [1..]
[('c',1),('o',2),('d',3),('e',4)]
Şimdi fonksiyon g (x,y)
Eğer y defa istediğini kopyalayan çoğaltmak işlevini kullanır. Yani x, y kere çoğaltırız.
Prelude> map g $ zip "code" [1..]
["c","oo","ddd","eeee"]
Dizgilerde bir listesi varsa, bunları concat
kullanarak birlikte arada kullanabilirsiniz: ürettiğimiz liste üzerinde bu işlevi eşlerseniz
Prelude> g ('z',4)
"zzzz"
sonuç almak. concatMap
, her bir harf ve sayı çiftine g
işlevini uygular ve ardından dizeyi son sonuca birleştirir.
Prelude> concat $ map g $ zip "code" [1..]
"coodddeeee"
Temelde: concat $ map g
->concatMap g
DÜZENLEME: çalıştığını şimdi, o da thusly bir satırda yapılabilir:
f x = concatMap (\(a,b)->replicate b a) $ zip x [1..]
Çıktı:
Prelude> f "lambda"
"laammmbbbbdddddaaaaaa"
Jonno ... Bu cevabı açıklayabilir misiniz, Birinin çok erken aşamalarında olan biri olarak haskell'i öğrenmek, yukarıdaki cevap sadece bana mantıklı gelmiyor. –
Açıklama için düzenlemeye bakın –
'g' uncurry ile değiştirilmem gerekir. kopyala. Aynı şeyi yapar, ancak standart Haskell kitaplığı işlevlerini kullanır. –
import Control.Monad
f = zip [1..] >=> uncurry replicate
Main> f "code"
"coodddeeee"
Güzel! Benim gibi insanlar için, operatörün tipini bilmeyenler için: "Soldan sağa Monasların bileşimi:" (> =>) :: Monad m => (a -> mb) -> (b -> mc) -> (a -> mc) '" –
Prelude> let l = "code" in concat $ [take y $ repeat (last $ take y l) | y <- [1..length l]]
"coodddeeee"
İnsanlar neden Liste comprehensions nefret ediyorsun verir?
Prelude> let f s = concat [ replicate x y | (x,y) <- zip [1..] s]
Prelude> f "code"
"coodddeeee"
veya uzantıları
Prelude> :set -XParallelListComp
Prelude> let f s = concat [ replicate x y | x <- [1..] | y <- s]
Prelude> f "code"
"coodddeeee"
- 1. nodejs: string manipülasyon
- 2. Basit haskell string yönetmek
- 3. Haskell printf - String
- 4. Haskell Parsec, oneOf'u [String]
- 5. Zeka - php dizi manipülasyon
- 6. Manipülasyon Python
- 7. DateTime manipülasyon
- 8. Fonksiyonel Saflık ben Haskell öğrenme üzerinde çalışıyorum, ben o tamamen işlevsel bir dildir anlıyorum Haskell
- 9. Öğrenme Etkinleştirme
- 10. Manipülasyon olayları tetiklenmiyor
- 11. SQLite Tarih/Saat Manipülasyon
- 12. Öğrenme Java,
- 13. C++ Çoklu Kalıtım Sorusu
- 14. Rol Nesne model sorusu
- 15. ADO.NET'i öğrenme
- 16. Öğrenme .. CodeIgniter
- 17. Haskell
- 18. Haskell
- 19. Haskell
- 20. Haskell, String hazır bilgilerini derleme zamanında birleştiriyor mu?
- 21. Bu dize manipülasyon kodunun uzay karmaşıklığı nedir?
- 22. Başlangıç sorusu: Python
- 23. SQL Geri alma sorusu
- 24. İki hızlı Mathematica sorusu
- 25. Basit WPF biçimlendirme sorusu
- 26. Birkaç sıralama sorusu
- 27. raylar3 + sıvı ayrıştırma sorusu
- 28. nginx kurulum sorusu
- 29. iOS iTunes Filesharing Sorusu
- 30. ios yetkilendirme sorusu
Eğer şimdiye kadar bu çözmek için yazdım kod sonrası Lütfen deli gitmek istiyorum. Aksi halde insanlar bunun ev ödevi olduğundan şüphelenebilirler. –
Sizi temin ederim, bu ev ödevi değildir :) Bir Haskell kitabındaki excersises aracılığıyla çalışıyordum ve beynim bunun üzerinde donuyordu. Bu noktada bildiğim şu ki, ++ operatörünü kullanmam gerekecek, bir çeşit dizi manipülasyonu ve olası uzunluk fonksiyonunu kullanabileceğim –