2013-05-07 30 views
-3

我需要在一個clisp中創建一個函數,它將添加一個集合中的所有奇數。例如子集(2,8),結果將是15(3 + 5 + 7 )。有什麼建議麼? 我確實有這樣的事情,其中​​a是一組的開始,b是它的結束。Lisp函數添加一個子集中的奇數

(defun add (a b) 
(if(and(< a x) (> b x)) 
    (if(even(x)) 
     ((setq (x (+a 1))) (+ x 2)) 
     ((setq(x a)) (+ x 2)) 
      ))) 

編輯:

(defun add (a b) 
(if(and(< a x) (> b x)) 
    (if(evenp x)) 
     ((setq (x (+a 1)) 
      (loop for x from a to b do (+ x 2)))) 
     ((setq(x a)) (+ x 2) 
      (loop for x from a to b do (+ x 2))) 
       )) 
+0

從第一個奇數等於起始範圍開始,循環加2並將它們全部加到總和中,直到超過範圍的末尾。 – Barmar 2013-05-07 07:47:03

+0

好吧,我得到了該算法應該如何工作,我只是不知道如何在lisp中實現它 – user2167174 2013-05-07 07:54:59

+0

顯示你的嘗試,我們不是在這裏爲你做你的功課。 – Barmar 2013-05-07 07:56:47

回答

0

我看到它是使用應用性編程的最簡單方法。

(defun range (max &key (min 0) (step 1)) 
     (loop for n from min below max by step 
     collect n)) 

可以使用範圍函數生成你這樣的間隔:

(range 8 :min 2) => (2 3 4 5 6 7) 

,然後用過濾刪除若非則:

(remove-if-not #'oddp (range 8 :min 2)) => (3 5 7) 

和應用除了結果:

(apply #'+ (remove-if-not #'oddp (range 8 :min 2))) => 15 

你可以用上面的功能太:

(defun add (a b) 
     (apply #'+ (remove-if-not #'oddp (range b :min a)))) 
+1

請勿使用APPLY,請使用REDUCE。 – 2013-05-07 11:56:57

+2

在Common Lisp中使用RANGE不太好,因爲它實際上創建了整個列表。用懶惰的語言,情況可能並非如此。 – 2013-05-07 11:58:02

2

最直接的方式做到這一點是LOOP。該LOOP解決方案是非常簡單的:

(defun sum-odds (start end) 
    (loop for i from start to end 
     when (oddp i) sum i)) 

(sum-odds 2 8) 
=> 15 

迭代,你也可以使用DO,但你必須要有點更明確一切是如何工作的(你有更多的選擇):

(defun sum-odds2 (begin end) 
    (do ((sum 0) 
     (i begin (1+ i))) 
     ((= i end) sum) 
    (when (oddp i) 
     (incf sum i)))) 

(sum-odds2 2 8) 
=> 15 

如果你確實使用了一個解決方案來創建一個包含整數範圍的列表(它創建了一堆垃圾收集的中間列表),正如其他一些答案中所建議的,你應該考慮你遍歷該列表的次數(這裏沒有理由多次遍歷它)。您可以使用REDUCE:key參數,使奇數看起來像自己,甚至數字看起來像0總結列表中的元素:

(defun sum-odds3 (list) 
    (reduce '+ list 
      :key (lambda (n) 
       (if (oddp n) 
        n 
        0)))) 

(sum-odds3 '(2 3 4 5 6 7 8)) 
=> 15 
1

我打算做我平時的特殊才能,並把對碼回顧帽子,但如果對第二次嘗試進行了適當格式化,那麼採取漸進式方法存在太多問題。你需要坐下來解釋你的代碼要做什麼。

具體而言,x發生了什麼?這是否意味着每次都要重新設置一個全局綁定,還是你的意思是定義一個本地綁定,並且意外地忘記了if在需要變量之前需要變量?你想用這些setq s來做什麼,以及你想用這些loops做什麼?(按照​​書面材料,什麼都不做)?


[暫時穿上代碼審查帽子]

首先登場,請format your code properly。這是一件小事,但它增加了很多可讀性。

(defun add (a b) 
    (if (and (< a x) (> b x)) 
    (if (evenp x)) 
    ((setq (x (+ a 1)) 
      (loop for x from a to b do (+ x 2)))) 
    ((setq (x a)) (+ x 2) 
     (loop for x from a to b do (+ x 2))))) 

並使用適當的縮進級別,相當多的錯誤,只是你掉下來的時候了。

  • 首先,除此之外if中有三個子句(該if和兩個setq S代表某種原因)。
  • 二,那秒if沒有條款,只是一個測試。這意味着它什麼都不做
  • 第三,你在if正文中調用一些非常奇怪命名的函數。我願意保證((setq (x a)) (+ x 2) (loop for x from a to b do (+ x 2)))不是你的意思,因爲這就是(+ x 2)(loop ...)的參數調用功能(setq (x a))
  • 第四,你用兩種不同的方式調用setq(setq (x (+ a 1))這是試圖設置調用功能x(+ a 1)NIL的結果。 (setq (x a)) (+ x 2)這試圖設置調用a上的函數xNIL的結果,然後評估和丟棄(+ x 2)
0

在解決語法問題之前,您還沒有面臨算法問題。你顯然已經猜到了解決方案,甚至還沒有編譯你的猜測。你的代碼不會編譯,也不會運行。你正在研究類似Lisp的語言,正是因爲它們允許輕微的探索。所以探索。

(defun add (a b) 
    (cond ((evenp a) (add (+ a 1) b)) 
     ((> a b) 0) 
     (t   (+ a (add (+ a 2) b)))))