2011-04-17 47 views
1

只是一個基本的Casaer密碼。我已經測試了所有的子函數,只是encryptChar()不是特別有用。我得到一個無限循環。它應該是遞歸的。以下是所有代碼:一個真正基本的SML問題,我似乎無法弄清楚(小碼)

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

回答

2

這裏的問題在於您誤用了=。在變量定義之外,=只是一個布爾函數,它檢查其參數是否相等。因此,如果您以asciiCode = ord(String.sub(msgStr, index)) + shiftAmnt;爲例,它將簡單地返回false(因爲asciiCode不等於ord(String.sub(msgStr, index)) + shiftAmnt),然後丟棄該結果(因爲您在;之後有其他表達式)。它不會重新分配asciiCode

SML中的變量是不可變的。如果要模擬可變變量,則可以使用ref:=運算符。不過,我不會推薦這種方法,因爲它通常不是很好的功能風格,在這種情況下不是必需的。更好的方法是以每個變量只分配一次的方式重寫代碼。

1

這確實是非常基本的,在這樣一個複雜的情況下遇到它真是令人驚訝。
您是否從其他語言移植過此內容?

你需要忘記你所瞭解的關於使用任務編程的一切。

let val x = y in something 

意味着或多或少的「在」某物「內,用'y'的值代替標識符'x'。
您無法更改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編程的介紹性文章。

相關問題