改进Lisp函数实现顺势疗法药物相关案例分组展示
顺势疗法药物检索程序分组输出优化方案
我正在开发一款顺势疗法药物检索程序,其中PRINTKEY函数用于根据用户输入的关键词(或部分关键词)返回所有部分匹配结果。当前函数输出为单条植物对应属性的条目,例如:
GINGER IS ANALGETIKUM
HOUTTUYNIA IS ANALGETIKUM
希望优化为按属性分组展示关联植物的格式,例如:
ANALGETIKUM is a property of INGWER, HOUTTUYNIA
已提供PLANTS数据集、PRINTKEY及PRINTKEY-HELPER函数代码,尝试过一段格式化代码但存在重复输出问题,寻求可行的改进方案。
现有代码片段
(DEFPARAMETER PLANTS '(...)) (DEFUN PRINTKEY(KEYWORD LIS)...) (DEFUN PRINTKEY-HELPER(KEYWORD LIS TYPE PLANT)...)
尝试的格式化代码片段
(FORMAT T "~A is a property of ~{~a~^, ~}.~%" (CAR LIS) (APPLY #'APPEND (MAPCAR (LAMBDA (ROW) (IF (FIND (CAR LIS) (CDR (ASSOC 'EIGENSCHAFTEN ROW))) (LIST(SECOND (ASSOC 'NAME ROW))))) PLANTS)))
优化方案:按属性分组去重输出
问题根源是当前代码未做分组去重,会遍历所有属性并重复输出同一属性的植物列表。可通过先构建属性到植物列表的映射表,再遍历映射表输出的方式解决。
实现步骤
- 遍历
PLANTS数据集,提取每个植物的属性与名称,构建以属性为键、植物名称列表为值的映射结构。 - 过滤出包含用户关键词的属性(支持部分匹配)。
- 遍历筛选后的映射结构,按目标格式输出。
示例代码
(defun print-key-grouped (keyword) ;; 构建属性到植物名称的哈希表映射 (let ((property-map (make-hash-table :test #'equal))) ;; 遍历所有植物,填充映射表 (dolist (plant PLANTS) (let ((name (second (assoc 'NAME plant))) (properties (cdr (assoc 'EIGENSCHAFTEN plant)))) (dolist (prop properties) ;; 匹配关键词(不区分大小写的部分匹配) (when (search keyword prop :test #'string-equal) (push name (gethash prop property-map)))))) ;; 遍历映射表,输出分组结果 (maphash (lambda (prop plants) ;; 去重并排序植物列表(可选,提升输出规整度) (let ((unique-plants (remove-duplicates plants :test #'string-equal))) (format t "~A is a property of ~{~a~^, ~}.~%" prop (sort unique-plants #'string-lessp)))) property-map)))
代码说明
- 哈希表
property-map自动实现属性的分组存储,避免同一属性重复处理。 search函数实现关键词的不区分大小写部分匹配,符合需求。remove-duplicates确保同一植物不会在同一属性下重复出现。- 可选的
sort函数让植物名称按字母顺序排列,输出更整洁。
内容的提问来源于stack exchange,提问作者Tuliodnw
相关产品推荐
相关产品推荐

