【问题标题】:SML how to get while on char list to return int?SML如何在char列表上返回int?
【发布时间】:2010-09-15 21:36:45
【问题描述】:

我有点难以弄清楚如何将每个已处理的字符恢复为 int 值。

函数应该像这样工作:val caesar = fn : int * int -> int

所以如果 k = 2466 且 n = 2,那么输出应该是 4688

希望代码不会太奇怪(我是 SML 新手)。

 (* Load Libs *)
    load "Int";
    load "Real";
    load "String";
    load "Char";
    load "List";


    fun caesar (k, n) =
      let
        fun k_string (i) = Int.toString(i)
        fun item_k_char (x, y) = Char.ord (List.nth (x, y))

        val val_k_string = k_string(k)
        val k_explode = String.explode(val_k_string)
        val counter = ref 0
        val counter_end = (String.size(val_k_string) - 1)

      in 
        while (!counter >= counter_end) do (
          item_k_char(k_explode, !counter) + n;
          counter := !counter + 1
        )
      end;

【问题讨论】:

    标签: sml


    【解决方案1】:

    while 循环并不是这里最好的工具。相反,您可以使用map,它为给定列表中的每个项目执行给定函数,并返回一个包含每次调用该函数的结果的新列表。

    换句话说:map (fn c => (Char.ord c) + 2) [#"2", #"4", #"6", #"6"] 将返回 [52,54,56,56]。您可以将其转换回 char 并使用 String.implode 获取字符串“4688”。

    您可能还想添加一些逻辑,以便数字“环绕”,即 caesar (7,7) 变为 4

    所以你的所有代码都变成了:

    fun caesar (k, n) =
      let
        val val_k_string = Int.toString k
        val k_explode = String.explode val_k_string
        val ints = map (fn c => (Char.ord c) + n) k_explode
        val wrappedAroundInts = map (fn i => (i - 48) mod 10 + 48) ints
        val chars = map Char.chr wrappedAroundInts
        val string = String.implode chars
      in
        Option.valOf (Int.fromString string)
      end
    

    【讨论】:

    • Wooh thx :) 你能解释一下 WrapdAroundInts 值函数吗,我不是 100% 确定我理解它。另一件事,我需要为有趣的凯撒的变体添加一个例外,我检查 k 是否 = 8。可以这样做吗? caesar2(k, n : int) = if Option.valOf (Int.fromString (String.size (Int.toString (k)))) != 8 then raise Fail "k must be 8 characters long"
    • @TBK:包装的工作方式如下:Char.ord 返回一个介于 48(#"0" 的 ASCII 值)和 57(#"9" 的 ASCII 值)之间的整数。添加n 后,该值可能大于 57(因此不再代表数字)。为了解决这个问题,我们减去 48 并将结果模 10。现在我们有一个介于 0 和 9 之间的数字。通过再次添加 48,我们再次得到一个介于 48 和 57 之间的数字,因此是一个有效数字。
    • @TBK:如果你想检查k是否为8,你可以做if k = 8 then。如果你想检查k是否有8位数字,你可以做if String.size (Int.toString k) = 8。如果要检查k是否没有8位,可以使用if String.size (Int.toString k) = 8。无需使用fromString,因为size 返回一个整数。
    • 超级,我真的很感激:D
    • @TBK:Ehrm,在我上一条评论中,我的意思是说“如果你想检查 k 是否没有 8 位数字,你可以使用 if String.size (Int.toString k) <> 8”(<> 而不是 @987654342 @)。不客气。
    猜你喜欢
    • 2019-11-22
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    相关资源
    最近更新 更多