1

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

2 回答 2

2

这里的问题是你在滥用=. 在变量定义之外,=它只是一个布尔函数,用于检查其参数是否相等。因此,例如asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;,如果您这样做,它将简单地返回false(因为asciiCode不等于ord( String.sub(msgStr, index) ) + shiftAmnt),然后将该结果丢弃(因为您在 之后有其他表达式;)。它不会重新分配asciiCode

SML 中的变量是不可变的。如果要模拟可变变量,可以使用refs 和:=运算符。但是我不会推荐这种方法,因为它通常不是很好的功能风格,在这种情况下也没有必要。更可取的方法是以每个变量只分配一次的方式重写代码。

于 2011-04-17T22:26:56.673 回答
1

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

你需要忘记你所知道的关于使用作业编程的一切。

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)

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

您最好掌握有关 ML 编程的介绍性文本。

于 2011-04-19T15:49:53.707 回答