簡體   English   中英

Haskell Int 列表:[123] 到 [1,2,3]

[英]Haskell List of Int : [123] to [1,2,3]

問題

我的 int 列表為 [123,123],我需要為 [1,2,3,1,2,3]

當前代碼

我使用遞歸嘗試了以下代碼

fat::[Int]->[Int]
fat [] = []
fat (a,b,c:xs) = a : b : c : fat xs

結論

我不知道如何在列表 [123,123] 中將值分別訪問為“1”、“2”、“3”

我建議在您列表的每個元素上使用此答案中給出的digs function。 它將Int拆分為數字列表( [Int] )。 然后你只需要連接結果列表。 這種“映射和連接結果”要求對於concatMap來說是一項完美的工作

fat :: [Int] -> [Int]
fat = concatMap digs

這給出了:

*Main> fat [123,123]
[1,2,3,1,2,3]

如果我理解正確的話,這就是你想要的。

splitNum :: Int -> [Int]
splitNum n | n <= 9     = [n]
           | otherwise  = (splitNum (n `div` 10)) ++ [n `mod` 10]

fat :: [Int] -> [Int]
fat x = concatMap splitNum x

splitNum 用於將 Int 轉換為 [Int],方法是將其拆分為十個提醒的除法,並將生成的 Int 附加到拆分后的 rest(遞歸!)

現在,有一個 function 將數字轉換為列表,go 通過輸入,將 splitNum 應用於內部列表中的任何數字並連接所有結果列表(列表理解!)

作為一個新的 Haskell 程序員,我會給你我對這個問題的想法。 只是因為我認為有很多選擇很好,尤其是來自不同經驗的不同人。

這是我對這個問題的看法:

  • 對於列表中的每個項目,使用 read 將該項目轉換為 char 列表。
  • 將該 char 列表發送到 function 中,該列表將該列表中的每個項目轉換為一個 int,然后返回一個 int 列表。
  • 將該整數列表連接到主列表中。

澄清:

  • [123, 234]
  • 123 變成 ['1', '2', '3']
  • ['1', '2', '3'] 變成 [1, 2, 3]
  • [1, 2, 3] 在主列表中獲得 concat
  • 循環重復 234 次。

util function 看起來像這樣:

import Char

charsToInts :: [Char] -> [Int]
charsToInts [] = []
charsToInts (x:xs) = digitToInt x : charsToInts xs

來自勢在必行的背景,這就是我解決它的方式。 可能比僅在數學上拆分數字要慢,但我認為展示一個替代方案會很有趣。

直截了當地指出問題,您不知道如何單獨訪問數字,因為您不了解 Haskell 類型和模式匹配。 讓我試着幫助消除你的一些誤解。

讓我們看看你的清單:

[123, 123]

它的類型是什么? 它顯然是一個整數列表,或[Int] 使用列表,您可以在構造函數:上進行模式匹配,lispers 將其稱為“cons”或“列表構造函數”。 您在:的左側放置了一個元素,在右側放置了另一個列表。 右邊的列表可以是空列表[] ,基本表示列表的結束。 Haskell 提供了“語法糖”以使列表更易於編寫,但[123,456]實際上被脫糖為123:(456:[]) 因此,當您進行模式匹配(x:y:z)時,您現在可以看到x將被分配123並且y將被分配456 z將是xy之后列表的 rest ; 在這種情況下,只剩下[]

現在,與:的模式匹配適用於列表 Int不是列表,因此您不能使用:Int的數字進行模式匹配。 但是, String列表,因為String[Char]相同。 因此,如果您將Int轉換為String ,則可以對每個字符進行模式匹配。

map show [123, 123]

map將 function 應用於列表的所有元素。 show可以采用Int並將其轉換為String 所以我們map show Int的列表以獲得String的列表。

["123", "123"]

現在讓我們將這些Strings轉換為Int的列表。 由於String只是[Char] ,我們將再次使用map

map digitToInt "123" -- this requires that you import Data.Char (digitToInt)

這會給我們[1,2,3] 列表中的每個Char都變成一個Int 這就是我們想要對列表["123", "123"]中的每個String執行的操作。 我們希望map digitToInt到每個字符串。 但是我們有一個String的列表。 那么我們該怎么辦? 我們map吧!

map (map digitToInt) ["123", "123"]

這會給我們[[1,2,3], [1,2,3]] 幾乎是我們想要的。 現在我們只需要將Int列表 ( [[Int]] ) 列表展平為Int列表 ( [Int] )。 我們怎么能做到這一點? 停止......胡歌時間! 搜索[[a]] -> [a] 我們發現第一個命中concat正是我們想要的。

讓我們把它們放在一起。 首先我們做map show[Int][String] 然后我們做map (map digitToInt)[String][[Int]] 然后我們做concat[[Int]][Int] 那我們就print出來吧!

import Data.Char (digitToInt)
main = print $ concat $ map (map digitToInt) $ map show $ [123, 123]

現在讓我們將大部分內容提取到 function fat

import Data.Char (digitToInt)
main = print $ fat [123, 123]
fat :: [Int] -> [Int]
fat xs = concat $ map (map digitToInt) $ map show $ xs

從這里你可以用幾種不同的方式讓它更漂亮。 concat $ mapconcatMap相同,並且由於我們 map 兩者(map digitToInt)並按順序show ,我們可以合並它們。 同樣讓它變得無意義,我們可以得到一個非常簡潔的定義:

fat = concatMap (map digitToInt . show)

為了完整起見,我按照@Ancide 的建議編寫了它

執行

fat' :: [Int] -> [Int]
fat' l = map (read) [[z] | z <- [x | k <- (map (show) l), x <- k]]         

說明

{- last result -}代表最后解釋的代碼的結果。

map (show) l

這需要l中的每個元素並將其轉換為[String]

[x | k <- {- last result -}, x <- k]

k遍歷最后一個結果中的所有元素時, x枚舉每個k中的所有字符。 所有這些都添加到列表中。 現在您有一個String ,分別是一個[Char] ,所有數字都彼此相鄰。

[[z] | z <- {- last result -}]

這部分從String中獲取每個Char並將其放入一個空String中。 注意[z]部分! 這會在z周圍創建一個列表,這與String相同(見上文)。 現在你有一個字符串列表,每個數字都有一個字符串。

map (read) {- last result -}

這將獲取最后一個結果中的每個項目並將其轉換回Int並將它們連接到[Int] 現在您有了想要結果的[Int]類型列表。

恢復

盡管這種實現是可能的,但由於所有類型轉換,它既不快,也不可讀。

玩弄列表單子我想出了這個。 幾乎相同的@Ankur 的解決方案,除了使用列表單子:

fat :: [Int] -> [Int]
fat is = is >>= show >>= return . digitToInt

如果你有兩個數字, ab ,那么你可以通過 10*a + b 將它們變成一個數字。 同樣的原則適用於三個。

聽起來這樣做的一種方法是將Every分成三個塊,然后將map a function 將三個列表變成一個數字。

這有幫助嗎?

You need a function to convert Integer to string... which is obviously Show function Another function to convert a Char to Integer which is "digitToInt" in module Char

在這里我們 go:

fat::[Int]->[Int]
fat [] = []
fat ls = concat $ map (map digitToInt) (map show ls)

請讓我知道它是否有效:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM