SML中的猪拉丁函数(运算符和操作数错误)

时间:2018-11-16 05:42:11

标签: sml smlnj

我正在使用Ullman(M97)第二版中的问题练习sml。我目前正在研究的问题是调用一个带一个单词的皮拉丁函数,然后将其爆炸,然后检查第一个字符是否是元音(a,e,i,o u)。如果是元音,则将字符列表内插到字符串中,并在末尾添加“ yay”。如果第一个字符不是元音,则函数将检查其余字符,直到遇到第一个元音为止。当这样做时,它将所有在第一个元音之前的字符都放在字符列表的末尾,将新字符列表内插到字符串中,并在其中添加“ ay”。

例如:

static boolean validate(String userName, String password) {
    // declare necessary variables
    String upperCase = ".*[A-Z].*";
    String lowerCase = ".*[a-z].*";
    String number = ".*[0-9].*";
    String special = ".*[^A-Za-z0-9 ].*";
    boolean valid = true;

    if (password.equals("-1")) {
        System.exit(0);
    }
    if (!password.matches(upperCase)) { // check to see if input has one upper case letter
        System.out.println("Password should contain at least one upper-case alphabet.");
        valid = false;
    }
    if (!password.matches(lowerCase)) { // check to see if input has one lower case letter
        System.out.println("Password should contain at least one lower-case alphabet.");
        valid = false;
    }
    if (!password.matches(number)) { // check to see if input has one number
        System.out.println("Password should contain at least one number.");
        valid = false;
    }
    if (!password.matches(special)) { // check to see if input has a special char.
        System.out.println("Password should contain at least one special character.");
        valid = false;
    }
    if (password.length() < 7 || password.length() > 10) { // make sure the password input = 7-10 char.
        System.out.println("Password should be within 7 to 10 characters in length.");
        valid = false;
    }
    if (password.matches(".*\\s.*")) { // check to see if input has white spaces
        System.out.println("Password should not contain whitespace.");
        valid = false;
    }
    if (password.matches(userName)) { // give error if user name and password are the same
        System.out.println("Password should not contain or be the same as username.");
        valid = false;
    }
    if (valid) {
        System.out.println("Password is valid");
    }

    return valid;
}

我已经完成了大多数问题,但是我仍然坚持为什么我的plx函数会给我这个问题:

- pl "able";
val it = "ableyay" : string

- pl "stripe";
val it = "ipestray" : string

fun isVowel (c::cs) = 
    if c = #"a" then true
    else if c = #"e" then true
    else if c = #"i" then true
    else if c = #"o" then true
    else if c = #"u" then true
    else false

fun cycle nil = nil
  | cycle (h :: hs) = hs @ [h]

fun aL (h::hs) =
    if isVowel(h) = true
    then h :: hs
    else aL (cycle (h :: hs))

fun plx (x) =
    if isVowel x = true
    then (implode x) ^ "yay"
    else implode (aL (x)) ^ "ay"

fun pl (x) =  plx (explode x)

我不确定如何解决它。

2 个答案:

答案 0 :(得分:1)

这是因为isVowel的类型是char list -> bool

如果您查看aL

fun aL (h::hs) = if isVowel(h) = true then h :: hs
                 else aL (cycle (h :: hs));

isVowel(h)意味着h必须是char list,这又意味着aL必须具有类型char list list -> char list list和{{1} }是一个错误。

要解决此问题,请将implode (aL x)更改为isVowel

char -> bool

并在fun isVowel c = ... 中写入isVowel (hd x)

答案 1 :(得分:0)

您可能会发现Exercism's SML track很有趣。甚至有Pig Latin练习。 :-)

爆炸,分析和内爆很普遍,但是效率不高,在某些情况下也不容易。正如molbdnilo指出的那样,isVowel应该接受char而不是char list作为输入:

fun isVowel c =
    c = #"a" orelse
    c = #"e" orelse
    c = #"i" orelse
    c = #"o" orelse
    c = #"u"

对于将单词转换为猪拉丁语的函数,您可以完全使用字符串函数来做到这一点:

fun piglatin (word : string) =
    let val firstLetter = String.sub (word, 0)
    in if isVowel firstLetter
       then word ^ "yay"
       else String.extract (word, 1, NONE) ^ str firstLetter ^ "ay"
    end

对此进行测试:

- piglatin "pig";
> val it = "igpay" : string

- piglatin "ant";
> val it = "antyay" : string

现在,有一些极端情况:

  • 如果单词是空的""会怎样?

    - piglatin "";
    ! Uncaught exception:
    ! Subscript
    
  • 如果单词是大写的"Ant"怎么办?

    - piglatin "Ant";
    > val it = "ntAay" : string
    

要使基于字符串的piglatin函数变得更健壮和 total ,则需要解决这两个问题。


以下是您发布的解决方案的一些反馈意见:

  • 不要写if P then true else Q;写P orelse Q
  • 不要写isVowel c = true;写isVowel c
  • aLplx并不是最好的函数名称;除了plcycleisVowelexplode和{{ 1}}。
相关问题