【问题标题】:Write three Scheme procedures to simulate these three gates: AND, OR and XOR编写三个 Scheme 程序来模拟这三个门:AND、OR 和 XOR
【发布时间】:2015-04-21 23:15:25
【问题描述】:

到目前为止,我假设最后两个应该是:

(define or-gate
  (lambda (a b)
    (if (= a 1)
        1
        (if (= b 1)
            1
            0))))

(define xor-gate
  (lambda (a b)
    (if (= a b)
        0
        1)))

...但是 AND 令人费解。如何实现?

【问题讨论】:

  • 我想向您展示如何在有序列表中输入节点的代码,但您删除了您的 qestiom。如果您仍然需要解决方案,您可以在我的个人论坛cpp.forum24.ru在论坛的第一部分(对于初学者)用英文提问,我会回答。:)

标签: functional-programming scheme racket


【解决方案1】:

如果我们记住= 可以接受两个以上的参数,那就很简单了:

(define and-gate
  (lambda (a b)
    (if (= a b 1)
        1
        0)))

换句话说:and 逻辑连接器是 true 当且仅当它的两个参数都是 true,对于所有其他参数它是 false

【讨论】:

    【解决方案2】:

    and 的真值表是什么?实际上,如果您有 andorxor 中的任何一个的真值表,那么算法是相同的。

    让我们创建一个接受真值表并返回计算门逻辑的函数

    (define (gate-logic-for-truth-table table)
      (lambda (a b)
        (vector-ref (vector-ref table b) a)))
    

    现在,使用and 的真值表,我们生成了and-gate 函数:

    (define and-gate (gate-logic-for-truth-table
                      '#(#(0 0)
                         #(0 1))))
    

    还有一个小测试:

    > (and-gate 0 0)
    0
    > (and-gate 0 1)
    0
    > (and-gate 1 0)
    0
    > (and-gate 1 1)
    1
    

    【讨论】:

      【解决方案3】:

      假设参数为10

      对于or,如果a1,则不需要查看b - 结果是1。否则结果为b
      对于and,如果a0,则不需要查看b - 结果是0。否则结果为b

      如果你想让它尽可能类似于or-gate,你可以将外部条件中的1s替换为0s:

      (define and-gate
          (lambda (a b)
              (if (= a 0)
                  0
                  (if (= b 1)
                      1
                      0))))
      

      或者,如果您想坚持与1 进行比较,您可以重新排列分支:

      (define and-gate
          (lambda (a b)
              (if (= a 1)
                  (if (= b 1)
                      1
                      0)
                   0)))
      

      可以缩短代码:

      (define and-gate
          (lambda (a b)
              (if (= a 1)
                  b
                  0)))
      

      (define or-gate
          (lambda (a b)
              (if (= a 1)
                  1
                  b)))
      

      但这是否更具可读性是非常个人化的。

      【讨论】:

        【解决方案4】:

        如果我们要使用门,我们可能应该从定义构造它们的方法开始。我的意思是我们将不得不建造三个大门。

        #lang racket
        
        ;; Gate Constructor
        (define (make-gate predicate)
          (lambda (A B)
            (predicate A B)))
        

        然后我们可以用一厢情愿的方式在高层次上定义门:

        (define and-gate
          (make-gate and-predicate))
        
        (define or-gate
          (make-gate or-predicate))
        
        (define xor-gate
          (make-gate xor-predicate))
        

        那么我们可以随意定义内部门逻辑:

        (define (and-predicate A B)
          (let ([a (if A 1 0)]
                [b (if B 1 0)])
            (= 2 (+ a b))))
        
        (define (or-predicate A B)
          (let ([a (if A 1 0)]
                [b (if B 1 0)])
            (< 0 (+ a b))))
        
        (define (xor-predicate A B)
          (let ([a (if A 1 0)]
                [b (if B 1 0)])
            (= 1 (+ a b))))
        

        然后我们进行真正的测试工作......好吧,也许我们实际上应该从编写测试开始。

        (module+ test
          (require rackunit
               rackunit/text-ui)
        
          (define (make-test-harness test-function)
            (define (test-harness ins outs)
              (if (or (null? ins)
                      (null? outs))
              'test-complete
              (begin
                (test-function (first ins)
                               (first outs))
                (test-harness (rest ins)
                              (rest outs)))))
            test-harness))
        
          (define gate-inputs
            '((#f #f)
              (#t #f)
              (#f #t)
              (#t #t)))
        
          (define and-truth-table
            '(#f #f #f #t))
        
          (define or-truth-table
            '(#f #t #t #t))
        
          (define xor-truth-table
            '(#f #t #t #f))
        
        
          (define (make-gate-test gate name)
            (lambda (input correct)
              (define A (first input))
              (define B (second input))
              (test-equal? name
                           (gate A B)
                           correct)))
        
          (define and-gate-test
            (make-gate-test and-gate "AND Gate Test"))
          (define or-gate-test
            (make-gate-test or-gate "OR Gate Test"))
          (define xor-gate-test
            (make-gate-test xor-gate "XOR Gate Test"))
        
          (define (and-tests)
            (define tests
              (make-test-harness and-gate-test))
            (tests gate-inputs and-truth-table))
        
          (define (or-tests)
            (define tests
              (make-test-harness or-gate-test))
            (tests gate-inputs or-truth-table))
        
          (define (xor-tests)
            (define tests
              (make-test-harness xor-gate-test))
            (tests gate-inputs xor-truth-table))
        
          (define-test-suite
            all-gate-tests
            (and-tests)
            (or-tests)
            (xor-tests))
        
          (run-tests all-gate-tests))
        

        运行测试

        racket@29761897.rkt> ,enter "/home/ben/StackOverflow/29761897.rkt"
        12 success(es) 0 failure(s) 0 error(s) 12 test(s) run
        0
        

        既然所有的测试都通过了,我们现在可以交作业了[一如既往地遵守学术政策]。

        注意事项

        使用真值 #f#t 为 Racket 的测试工具提供了更清晰的挂钩。它还允许直接编写谓词,而不是序列化和反序列化 10

        【讨论】:

          【解决方案5】:

          这是一个简单的定义,其中真值表很清楚:

          (define (and-gate a b)
            (cond
              [(and (= a 0) (= b 0))  0]
              [(and (= a 0) (= b 1))  0]
              [(and (= a 1) (= b 0))  0]
              [(and (= a 1) (= b 1))  1]))
          

          如果我们注意到只有一个子句的结果为 1,而所有其他子句的结果为 0, 我们可以写:

          (define (and-gate a b)
            (cond
              [(and (= a 1) (= b 1))  1]
              [else                   0]))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-18
            • 1970-01-01
            • 1970-01-01
            • 2015-08-03
            • 2020-12-02
            • 1970-01-01
            相关资源
            最近更新 更多