看来我得把它做得详细些,这是我的作业。我不想抄袭你写的代码。我是个新手,我想学的是如何将一个主题分解成一个整体,然后专注于我应该使用什么功能来解决这个问题。我自己解决这些问题有点困难,因为我完全是Lisp的新手,实际上是如何编程的。希望你能帮我个忙。
问题是:有一个给定的常量
(defconstant *storms* '((bob 65)
(chary 150)
(jenny 145)
(ivan 165)
(james 120)))每一场风暴都有一个名称和风速的列表。
风速可分为以下几类:
39-74 tropical→
75-95 cat-1→
96-110 cat-2→
111-130 cat-3
131-155→→
156个或更多cat-5→
现在我必须编写两个函数:
storm-categories应该生成分类名,如:(bob tropical)、(chary cat-1)、…storm-distribution应该生成每个类别中的风暴数,如:(cat-1 1)、(cat-2 0)、…我试图解决这个问题的方法是:
if语句来判断风速的类型:
(if (和(> x 39) (< x 73)) (打印‘热带“) (if (和(> x 74) (< x 95)) (打印'cat-1)) (if (和(> x 96) (< x 110)) (打印'cat-2)) (if (和(> x 111) (< x 130)) (打印’cat-3)) (if (和(> x 131) ) (< x 155))打印‘猫-4’)(如果(和(> x 156)) (打印'cat-5))65)替换为风型(如cat-1)
(x在风暴中的循环)我只是简单地了解了第一个函数,但仍然不知道如何实现它。我没有触及分配函数,因为我仍然停留在第一个。
发布于 2011-09-14 08:21:50
好了,罗西亚,你已经发布了你的答案。这是我几分钟后被黑的,但它应该给你一些想法:
首先,让我们从数据开始:
(defparameter *storms2004*
'((BONNIE 65)
(CHARLEY 150)
(FRANCES 145)
(IVAN 165)
(JEANNE 120)))
(defparameter *storm-categories*
'((39 73 tropical-storm)
(74 95 hurricane-cat-1)
(96 110 hurricane-cat-2)
(111 130 hurricane-cat-3)
(131 155 hurricane-cat-4)
(156 nil hurricane-cat-5)))检查一个值是否介于两个边界之间的函数。如果右边框也可能丢失(零)。
(defun between (value a b)
(<= a value (if b b value)))请注意,Lisp允许具有两个以上参数的比较谓词。
让我们找出风暴的种类。Lisp函数FIND和FIND-IF在列表中查找内容。
(defun storm-category (storm-speed)
(third (find-if (lambda (storm)
(between storm-speed (first storm) (second storm)))
*storm-categories*)))让我们计算一下每一场风暴的类别。因为我们得到了一个列表(风暴风速),我们只是映射到计算列表上的类别的函数。我们需要返回一份风暴和类别的清单。
(defun storm-categories (list)
(mapcar (lambda (storm)
(list (first storm)
(storm-category (second storm))))
list))现在我们使用相同的风暴列表,但是使用哈希表来跟踪每个类别中有多少风暴。MAPC类似于MAPCAR,但只是因为更新哈希表的副作用。NCF增加计数。填充哈希表后,需要使用MAPHASH对其进行映射。对于表中的每一对键和值,我们只需将其推入结果列表,然后返回该结果。
(defun storm-distribution (storms)
(let ((table (make-hash-table)))
(mapc (lambda (storm)
(incf (gethash (second storm) table 0)))
(storm-categories storms))
(let ((result nil))
(maphash (lambda (key value)
(push (list key value) result))
table)
result)))测试:
CL-USER 33 > (storm-category 100)
HURRICANE-CAT-2
CL-USER 34 > (storm-categories *storms2004*)
((BONNIE TROPICAL-STORM)
(CHARLEY HURRICANE-CAT-4)
(FRANCES HURRICANE-CAT-4)
(IVAN HURRICANE-CAT-5)
(JEANNE HURRICANE-CAT-3))
CL-USER 35 > (storm-distribution *storms2004*)
((HURRICANE-CAT-5 1)
(HURRICANE-CAT-4 2)
(HURRICANE-CAT-3 1)
(TROPICAL-STORM 1))在我看来很好。
发布于 2011-09-10 00:55:37
副局长是错的。让你的输入成为常量是没有意义的。用DEFVAR或DEFPARAMETER定义的变量很好。
而不是使用COND。COND允许测试几种条件。
你不想用印刷品。为什么要打印一些东西。你想要计算一个值。
RPLACA也错了。这是用于破坏性改造的。你不会想要那样的。你想要创造一个新的价值。类似于RPLACA的内容可能会在函数分发版中使用(见下文)。
使用函数抽象。哪些功能有用?
其中最复杂的是函数的分布。通常,人们会使用哈希表或assoc列表作为中间帮助,以保持事件的计数。映射输入列表并更新相应的计数。
另外:关于基本Lisp的一个很好的介绍是“普通Lisp:符号计算的绅士介绍”一书,它可以作为PDF免费下载。更有趣的也是对Lisp的基本介绍是“利普之地”一书。
发布于 2011-09-14 07:27:44
终于完成了这个问题。第二部分真的让我发疯了。我不知道如何使用hashtable或assoc列表来解决它。无论如何,任务已经完成了,但我想知道如何简化它.希望你们能帮我。谢谢你的帮助,乔斯温,你的主意真的对我很有帮助.
(defconstant *storms2004* '((BONNIE 65)(CHARLEY 150)(FRANCES 145)(IVAN 165)(JEANNE 120)))
(defun storm-category (x) ; for given windspeed return the category
(cond
((and (> x 39) (< x 73) 'tropical-storm))
((and (> x 74) (< x 95) 'hurricane-cat-1))
((and (> x 96) (< x 110) 'hurricane-cat-2))
((and (> x 111) (< x 130) 'hurricane-cat-3))
((and (> x 131) (< x 155) 'hurricane-cat-4))
( t 'hurricane-cat-5)
)
);end storm-category
(defun storm-categories (lst) ;for a list of storm and windspeed return storm's name and wind type
(let ((result nil))
(dolist (x lst (reverse result)) ;
(push
(list (first x) (storm-category (second x)) ) result)
)
)
);end storm-categories
(defun storm-distribution (lst)
(setq stormcategories '(tropical-storm hurricane-cat-1 hurricane-cat-2 hurricane-cat-3 hurricane-cat-4 hurricane-cat-5))
(setq stormlist (storm-categories lst))
(let( (tropicalcount 0)
(hurricane-cat-1count 0)
(hurricane-cat-2count 0)
(hurricane-cat-3count 0)
(hurricane-cat-4count 0)
(hurricane-cat-5count 0)
(result nil)
)
(dolist (y stormlist )
(cond
((eql (second y) 'tropical-storm) (setq tropicalcount (+ tropicalcount 1)))
((eql (second y) 'hurricane-cat-1) (setq hurricane-cat-1count (+ hurricane-cat-1count 1)))
((eql (second y) 'hurricane-cat-2) (setq hurricane-cat-2count (+ hurricane-cat-2count 1)))
((eql (second y) 'hurricane-cat-3) (setq hurricane-cat-3count (+ hurricane-cat-3count 1)))
((eql (second y) 'hurricane-cat-4) (setq hurricane-cat-4count (+ hurricane-cat-4count 1)))
((eql (second y) 'hurricane-cat-5)(setq hurricane-cat-5count (+ hurricane-cat-5count 1)))
)
);ebd dolist
(push
(list (list 'tropicalstorm tropicalcount )
(list 'hurricane-cat-1 hurricane-cat-1count)
(list 'hurricane-cat-2 hurricane-cat-2count )
(list 'hurricane-cat-3 hurricane-cat-3count )
(list 'hurricane-cat-4 hurricane-cat-4count )
(list 'hurricane-cat-5 hurricane-cat-5count )
) ;end list
result) ;end push
);end let
);end distributionhttps://stackoverflow.com/questions/7368882
复制相似问题