奇数和偶数之和

Sum of odd and even numbers

我是 lisp 编程的新手,我正在尝试创建一个接受六个数字并检查每个数字是奇数还是偶数的程序。


(princ"Input six number: ")
(setq a(read))
(setq b(read))
(setq c(read))
(setq d(read))
(setq e(read))
(setq f(read))
(format t "~% ~d" a)
(format t "~% ~d" b)
(format t "~% ~d" c)
(format t "~% ~d" d)
(format t "~% ~d" e)
(format t "~% ~d" f)
(if(= 0(mod a 2))
   (print"even")
   (print"odd"))
   (if(= 0(mod b 2))
      (print"even")
      (print"odd"))
      (if(= 0(mod c 2))
         (print"even")
         (print"odd"))
         (if(= 0(mod d 2))
            (print"even")
            (print"odd"))
             (if(= 0(mod e 2))
                (print"even")
                 (print"odd"))
                 (if(= 0(mod f 2))
                    (print"even")
                    (print"odd"))
                    (terpri)

您有很多代码如下所示:

(if(= 0(mod ... 2))
   (print"even")
   (print"odd"))

(这可能是一个 copy/paste 问题,但在您的问题中,它们越来越向右缩进。但是它们没有嵌套,它们都处于相同的深度(它们是顶层表达式)所以按照惯例它们不应该缩进)。

第一步是使用像这样的函数将它们因式分解:

(defun check-even-odd (number)
  (if (= 0 (mod number 2))
      (print "even")
      (print "odd")))

上面定义了一个名为 check-even-odd 的函数,有一个参数 number,它应用了与您最初对任意数字相同的逻辑。

您的其余代码可以简化为:

(check-even-odd a)
(check-even-odd b)
(check-even-odd c)
(check-even-odd d)
(check-even-odd e)
(check-even-odd f)

现在,您可以定义两个额外的全局变量:

(defparameter total-even 0)
(defparameter total-odd 0)

他们每个人都有一个sum,初始化为0。

您可以按如下方式重写 check-even-odd 函数来更新计数器。首先,让我们使用 cond 重写当前代码,因为我们将需要在每种情况下执行多个操作,而 if 每个分支只接受一个表达式(组合 ifprogn 有点难看):

(defun check-even-odd (number)
  (cond
    ((= 0 (mod number 2))
     (print "even"))
    (t
     (print "odd"))))

以上内容与原始代码相同。

为了将变量递增一定量,您可以使用INCF:

(defun check-even-odd (number)
  (cond
    ((= 0 (mod number 2))
     (print "even")
     (incf total-even number))
    (t
     (print "odd")
     (incf total-odd number))))

当您执行整个脚本时,总数将被初始化为零,然后每次调用 check-even-odd 都会将数字添加到适当的计数器。

备注:

  • 您可能会发现其他可以使用函数来抽象重复代码的地方
  • 在初始化 ab 等时,您应该使用 defparameter 而不是 setq,否则变量不会 声明 并且在未声明的变量上调用 setq 是不标准的
  • 事实上,可以在没有任何全局状态的情况下重写整个程序,这可能是一个很好的下一个练习
  • 您可以泛化更少或更多的数字而不是 6,您需要编写一个循环或递归函数来重复相同的代码任意时间
  • Input/output 可能需要刷新(参见 finish-outputclear-input),否则在缓冲基础流时您可能会遇到奇怪的行为。