2016-03-31 165 views
-2

我想創建一個SML函數,根據它接受的字符串返回true或false。如果它只包含數字,則返回true,否則返回false。SML檢查一個字符串是否只包含數字

例如: 「4124」 - 真正的

「543.234」 - 假

「F42」 - 假

「344克」 - 假

我並不擅長使用SML,任何幫助將不勝感激。

+1

你嘗試過什麼?這是作業,重點是從使用基本遞歸的第一原理開始,或者是其他事情需要的實際問題(在這種情況下,使用「List.all」和「Char.isDigit」的單行解決方案'是要走的路)? –

回答

1
fun foo xs = length (List.filter (Char.isDigit) xs) = length xs; 

fun boo xs = foo (explode xs); 

根據需要重命名該函數。

fun boo xs = List.all (Char.isDigit) (explode xs) 

也有效。

1

定義

val allDigits = List.all Char.isDigit o explode; 

(或類似的東西)是自然和優雅,但有缺點,它掃描過來的數據兩次,第一次創建人物的名單,另一次檢查,如果一切這些字符是數字。 SML的急切評估意味着即使第一個字符不是數字,也會創建整個列表。這會導致該功能例如採取超過200,000步驟來驗證Moby Dick的文本不是全部數字。

解決方案是抵制爆炸的字符串。相反,使用索引。

是有幫助的第一引入功能,其中當傳遞的函數int -> bool類型的f和一對整數ab返回真,如果在間隔[a,b)所有整數滿足謂詞f

fun allInRange f (a,b) = 
    if b <= a then 
     true 
    else 
     f a andalso allInRange f (a+1,b); 

由於SML短路andalso,只要在範圍內找到f的反例(如果有的話 - 否則返回true當然),遞歸終止。

最後,

fun allDigits s = 
    let 
     fun f i = Char.isDigit (String.sub (s,i)) 
    in 
     allInRange f (0, String.size s) 
    end; 
相關問題