1

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);
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 に答える