【问题标题】:Converting a list containing a binary number to decimal and hexadecimal in scheme在方案中将包含二进制数的列表转换为十进制和十六进制
【发布时间】:2012-09-26 03:24:56
【问题描述】:

我对方案很陌生。我知道如何从十进制转换为二进制,但我无法提供反过来转换的逻辑。我想从二进制数列表中获取一个十进制数。

十进制示例:

(decimal '(1 0 1)) ---> 5

十六进制示例:

(hexadecimal '(1 0 0 0 1)) ----> 12

到目前为止,我认为可以将列表的最后一个数字乘以 2i,其中 i 表示列表中的位置,因此最后一个数字乘以 1,即下一个接两个,以此类推。最后在每个递归循环中添加这些数字。不知道如何执行这个想法,也不知道它是否可行。

【问题讨论】:

  • 这个问题对输入列表中二进制数字的排序有点不清楚,输入示例无助于澄清。考虑输入'(1 0 0)。现在,列表的最后一个数字是多少,第一个数字是多少?我会说0是最后一个,1是第一个。不要将它们乘以 2^i,其中 i 是列表中数字的位置。第一个数字在位置 0,最后一个数字在位置 2,是吗?那么我们有 1*2^0 + 0*2^2 = 1。或者,第一个数字在位置 2,最后一个数字在位置 0,所以我们有 1*2^2 + 0*2^0 = 4. 是哪个?

标签: list binary scheme hex decimal


【解决方案1】:

规范中的输入不清楚,但是假设 OP 想要转换从左到右读取的二进制数,我们需要先颠倒数字顺序,以便我们乘坐的第一辆车是最低有效位;将每个后续的 2 幂应用于下一个有效位。为了处理函数内部的反转,可以使用命名的 let ,它允许我们在反转列表之后仅递归 let 的主体。 Guile Scheme 中的一种方法如下所示:

(define (binary->decimal binary-list)
  "Calculate decimal equivalent of list of binary"
  (let loop ((rev-bl (reverse binary-list)))
    (if (null? rev-bl)
        0
        (+ (car rev-bl) (* 2 (loop (cdr rev-bl)))))))

【讨论】:

  • 与其断言另一个答案是错误的,然后声明输入需要反转并命名为let,不如讨论为什么需要反转输入,以及为什么命名需要let。当然,也有其他方法可以解决这个问题。另外,仅供参考,Scheme 没有文档字符串;最好使用 cmets,因为它们没有被评估。
  • 确实不清楚另一个答案是否错误,因为 OP 不清楚输入列表中二进制数字的顺序。我投票结束这个问题,因为“需要细节或清晰度。
  • 是的,公平点,因为 OP 使用了回文的数字示例,规范不清楚。尽管大多数人会假设在没有规范的情况下从左到右读取二进制文件。我将更新我的评论以突出显示这一点,并解释命名的 let 用法。注意文档字符串是 Guile 的一部分 - 我会澄清我的答案是 Guile Scheme。
  • 这是一个很好的收获,我一开始同意你的看法,但是由于各种原因,可能会颠倒提供二进制数字列表(即,该列表不必是二进制数字的直接表示) )。我怀疑 OP 在描述他们提出的算法时有点倒退,但我认为我们不会收到他们的回复。我忘记了 Guile 文档字符串;我在 Common Lisp 中使用它们,但它们在 Scheme 或 Racket 中不是标准的,而且我首选的 Scheme (Chez) 没有它们。 IAC,我 +1。
【解决方案2】:

您对解决方案的书面描述是正确的——您只需要 做的是执行它。几点建议:

  • 如果你颠倒列表,逻辑会更容易
  • 将每个数字的权重和累加和传递为 递归函数的参数使其更简单

你在正确的轨道上——继续努力。伪代码尝试可能 让你更清楚。

【讨论】:

    【解决方案3】:
    (defun bin-list-to-dec (lst)
      (reduce (lambda (x y) (+ (* x 2) y)) lst))
    

    【讨论】:

      【解决方案4】:
      (define (binary->natural lon)
        (if (null? lon)
            0 
            (+ (car lon) (* 2 (binary->natural (cdr lon))))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-18
        • 2012-06-26
        • 2014-10-30
        • 1970-01-01
        • 2020-09-10
        • 2023-04-05
        • 1970-01-01
        • 2012-04-08
        相关资源
        最近更新 更多