一个非常基本的 SML 问题,我似乎无法弄清楚(小代码)

发布于 2024-11-01 18:22:04 字数 1128 浏览 4 评论 0原文

只是一个基本的卡萨密码。我已经测试了所有的子函数,只是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮凉 2024-11-08 18:22:04

这里的问题是您滥用了 =。在变量定义之外,= 只是一个布尔函数,用于检查其参数是否相等。因此,如果您执行 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 example asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;, it will simply return false (because asciiCode is not equal to ord( String.sub(msgStr, index) ) + shiftAmnt) and then throw that result away (because you have additional expressions after the ;). It will not reassign asciiCode.

Variables in SML are immutable. If you want to emulate mutable variables you can use refs 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.

浮光之海 2024-11-08 18:22:04

这确实是非常基本的问题,令人惊讶的是您在如此复杂的情况下遇到了它。
你是从其他语言移植的吗?

您需要忘记有关使用作业进行编程的所有知识。

let val x = y in something

或多或少意味着“在‘某物’内,将标识符‘x’替换为‘y’的值”。
您无法更改 x 的值。

进行替换(这不是实际的评估顺序或任何内容,但它应该让您了解发生了什么):

   encryptChar("THIS", amount, 0)

=>

let val asciiCode = 0  
in  
    if (not (String.sub("THIS", 0) = #" ")) then  
    (  
        asciiCode = ord( String.sub("THIS", 0) ) + amount;  
        if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26  
        else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26  
        else asciiCode = asciiCode;  
        "THIS" = replace("THIS", 0, chr(asciiCode))  
    )  
    else asciiCode = asciiCode;  
    0 = 0 + 1;  
    if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
    else str 
end ;

=>

        if (not (String.sub("THIS", 0) = #" ")) then  
        (  
            0 = ord( String.sub("THIS", 0) ) + amount;  
            if (0 < ord(#"A")) then 0 = 0 + 26  
            else if (0 > ord(#"Z")) then 0 = 0 - 26  
            else 0 = 0;  
            "THIS" = replace("THIS", 0, chr(0))  
        )  
        else 0 = 0;  
        0 = 0 + 1;  
        if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
        else str  

=>

        if (not (String.sub("THIS", 0) = #" ")) then  
        (  
            0 = ord( String.sub("THIS", 0) ) + amount;  
            if true then false
            else if false then false
            else true;
            false
        )  
        else true;  
        false;  
        if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
        else "this" 

->

        if (not false) then  
        (  
            false;
            false;
            false
        )  
        else true;  
        false;  
        if true then encryptChar("THIS", amount, 0)  
        else "THIS" 

=>

        (  
            false;
            false;
            false
        )  
        false;  
        encryptChar("THIS", amount, 0)

=>

    encryptChar("THIS", amount, 0)

这就是你的无限循环的来源。

您最好掌握有关机器学习编程的介绍性文本。

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.

let val x = y in something

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):

   encryptChar("THIS", amount, 0)

=>

let val asciiCode = 0  
in  
    if (not (String.sub("THIS", 0) = #" ")) then  
    (  
        asciiCode = ord( String.sub("THIS", 0) ) + amount;  
        if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26  
        else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26  
        else asciiCode = asciiCode;  
        "THIS" = replace("THIS", 0, chr(asciiCode))  
    )  
    else asciiCode = asciiCode;  
    0 = 0 + 1;  
    if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
    else str 
end ;

=>

        if (not (String.sub("THIS", 0) = #" ")) then  
        (  
            0 = ord( String.sub("THIS", 0) ) + amount;  
            if (0 < ord(#"A")) then 0 = 0 + 26  
            else if (0 > ord(#"Z")) then 0 = 0 - 26  
            else 0 = 0;  
            "THIS" = replace("THIS", 0, chr(0))  
        )  
        else 0 = 0;  
        0 = 0 + 1;  
        if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
        else str  

=>

        if (not (String.sub("THIS", 0) = #" ")) then  
        (  
            0 = ord( String.sub("THIS", 0) ) + amount;  
            if true then false
            else if false then false
            else true;
            false
        )  
        else true;  
        false;  
        if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)  
        else "this" 

->

        if (not false) then  
        (  
            false;
            false;
            false
        )  
        else true;  
        false;  
        if true then encryptChar("THIS", amount, 0)  
        else "THIS" 

=>

        (  
            false;
            false;
            false
        )  
        false;  
        encryptChar("THIS", amount, 0)

=>

    encryptChar("THIS", amount, 0)

Which is where your infinite loop came from.

You would do well to get hold of an introductory text about ML programming.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文