【问题标题】:Count and print matching values in SML在 SML 中计算和打印匹配值
【发布时间】:2020-12-24 06:36:04
【问题描述】:

根据分配的参数,我不能使用模式或折叠,这是解决更大问题的特定方法的玩具示例。

当我运行代码时,我自然会得到一个“0”。那么问题来了,怎么才能得到a_count的最终值呢?

fun num_counter(numbers: int list, a_number: int) =
     let val count = 0
             in
                 let fun count_num(numbers: int list, a_count: int) =
         if null numbers
         then 0
         else if (hd numbers) = a_number
         then count_num(tl numbers, count + 1)
         else count_num(tl numbers, count)
     in
     count       
     end
     end

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    你可以用折叠把它写得更短:

    fun num_counter (numbers, a_number) =
        let fun count (b_number, total) =
                if a_number = b_number
                then total + 1
                else total
        in foldl count 0 numbers
        end
    

    这里foldl接受三个参数:函数count在访问每个数字时累积结果,numbers中的b_numbertotal的初始值为0和要折叠的数字,numbers。当foldl 访问了最后一个数字时,它使用total 中的最后一个累积作为结果。

    foldl 本身定义为like this

    fun foldl f e []      = e
      | foldl f e (x::xr) = foldl f (f(x, e)) xr
    

    或者你可以filterlength 一起花费更多:

    fun num_counter (numbers, a_number) =
        length (filter (fn b_number => a_number = b_number) numbers)
    

    【讨论】:

      【解决方案2】:

      您的代码有几个问题:

      1. 您的递归函数 count_num 永远不会被调用。
      2. 您的递归通过返回0 而不是结果而终止 到目前为止,你已经积累了 (a_count)。
      3. 参数a_count 之间存在一些混淆,因为我 理解持有a_numbercount的出现次数 在第二行声明。

      这里有一些更正:

      fun num_counter(numbers: int list, a_number: int) = let
          fun count_num(numbers: int list, count: int) =
            if null numbers
            then count  (*  reached the end of the list =>
                            returned the number of occurences computed  *)
            else if (hd numbers) = a_number
            then count_num(tl numbers, count + 1)
            else count_num(tl numbers, count)
      in
          count_num (numbers, 0)  (*  first call of count_num,
                                      count initiated to 0  *)
      end;
      

      另外请注意,您可以使用模式匹配来增强 你的递归函数:

      fun num_counter(numbers: int list, a_number: int) =
        let fun count_num([], count) = count
              | count_num(i :: tl, count) =
                count_num(tl, if i = a_number then count + 1 else count)
        in
            count_num (numbers, 0)
        end;
      

      【讨论】:

      • 这行得通。我还没弄清楚什么时候进入“in”子句。
      猜你喜欢
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多