首页 > 解决方案 > 奇数和偶数之和

问题描述

我是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)

标签: lispclisp

解决方案


你有很多看起来像这样的代码:

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

(这可能是复制/粘贴问题,但在您的问题中,它们越来越向右缩进。但是它们不是嵌套的,它们都处于相同的深度(它们是顶级表达式),因此按照惯例它们不应该缩进)。

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

(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)

他们每个人都有一个和,并被初始化为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都会将数字添加到适当的计数器。

笔记:

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

推荐阅读