我正在使用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)
我不确定如何解决它。
答案 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
。aL
和plx
并不是最好的函数名称;除了pl
和cycle
,isVowel
,explode
和{{ 1}}。