一个非常基本的 SML 问题,我似乎无法弄清楚(小代码)
只是一个基本的卡萨密码。我已经测试了所有的子函数,只是 encryptChar() 不是特别有效。我得到一个无限循环。它应该是递归的。这是所有代码:
fun replace (str : string, index : int, newChar : char) : string = String.substring(str,0,index) ^ String.str(newChar) ^ String.substring(str,index+1,(size str) - index - 1;
fun encryptChar (msgStr : string, shiftAmnt : int, index : int) : string =
let val asciiCode = 0
in
if (not (String.sub(msgStr, index) = #" ")) then
(
asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;
if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26
else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26
else asciiCode = asciiCode;
msgStr = replace(msgStr, index, chr(asciiCode))
)
else asciiCode = asciiCode;
index = index + 1;
if (index < (size msgStr - 1)) then encryptChar(msgStr, shiftAmnt, index)
else msgStr
end
;
fun encrypt(msgStr : string, shiftAmnt : int) : string = encryptChar (String.map Char.toUpper msgStr, shiftAmnt mod 26, 0);
Just a basic Casaer Cipher. I've tested all of the sub functions, just encryptChar() does not particularly work. I get an infinite loop. It's supposed to be recursive. Here's the all code:
fun replace (str : string, index : int, newChar : char) : string = String.substring(str,0,index) ^ String.str(newChar) ^ String.substring(str,index+1,(size str) - index - 1;
fun encryptChar (msgStr : string, shiftAmnt : int, index : int) : string =
let val asciiCode = 0
in
if (not (String.sub(msgStr, index) = #" ")) then
(
asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;
if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26
else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26
else asciiCode = asciiCode;
msgStr = replace(msgStr, index, chr(asciiCode))
)
else asciiCode = asciiCode;
index = index + 1;
if (index < (size msgStr - 1)) then encryptChar(msgStr, shiftAmnt, index)
else msgStr
end
;
fun encrypt(msgStr : string, shiftAmnt : int) : string = encryptChar (String.map Char.toUpper msgStr, shiftAmnt mod 26, 0);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这里的问题是您滥用了
=
。在变量定义之外,=
只是一个布尔函数,用于检查其参数是否相等。因此,如果您执行asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;
操作,它将简单地返回false
(因为asciiCode
code> 不等于ord( String.sub(msgStr, index) ) + shiftAmnt
) ,然后丢弃该结果(因为;
之后还有其他表达式) 。它不会重新分配asciiCode
。SML 中的变量是不可变的。如果您想模拟可变变量,可以使用 ref 和 := 运算符。然而,我不推荐这种方法,因为它通常不是很好的功能风格,并且在这种情况下没有必要。更好的方法是以每个变量仅分配一次的方式重写代码。
The problem here is that you're misusing
=
. Outside of a variable definition,=
is simply a boolean function which checks its arguments for equality. So if you do for exampleasciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;
, it will simply returnfalse
(becauseasciiCode
is not equal toord( String.sub(msgStr, index) ) + shiftAmnt
) and then throw that result away (because you have additional expressions after the;
). It will not reassignasciiCode
.Variables in SML are immutable. If you want to emulate mutable variables you can use
ref
s and the:=
operator. However I would not recommend that approach as it is generally not good functional style and not necessary in this case. The preferable approach would be to rewrite the code in a way that each variable is only assigned once.这确实是非常基本的问题,令人惊讶的是您在如此复杂的情况下遇到了它。
你是从其他语言移植的吗?
您需要忘记有关使用作业进行编程的所有知识。
或多或少意味着“在‘某物’内,将标识符‘x’替换为‘y’的值”。
您无法更改 x 的值。
进行替换(这不是实际的评估顺序或任何内容,但它应该让您了解发生了什么):
=>
=>
=>
->
=>
=>
这就是你的无限循环的来源。
您最好掌握有关机器学习编程的介绍性文本。
This is very basic indeed, and it's surprising that you ran into it in such a complicated situation.
Did you port this from some other language?
You need to forget everything you know about programming using assignments.
means more or less "within 'something', replace the identifier 'x' with the value of 'y'".
There is no way for you to change the value of x.
Do the substitution (this is not the actual evaluation order or anything, but it should give you an idea of what's going on):
=>
=>
=>
->
=>
=>
Which is where your infinite loop came from.
You would do well to get hold of an introductory text about ML programming.