动态规划与宏
Posted Lisp与他们
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划与宏相关的知识,希望对你有一定的参考价值。
以前上课时,没认真学习数据结构和算法,虽然之后自己有在学,但总是学到一半就停下了,导致现在算法方面欠缺有点大。这一次求解字符串中的最长回文子串问题,并没有什么好的思路,但也想了一个:找出所有重复的字符,然后查看相同字符间的子字符串是否组成回文子串。
而在这里,使用动态规划则更加优美。不过先得知道什么是动态规划。
动态规划(英语:Dynamic programming,简称 DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划背后的思路是把一个给定的问题切分成不同部分(即子问题)再求解,再根据子问题的解以得出原问题的解。在这个问题上,假设 F(s)
是字符串 s
的最长回文子串,则 F(s) = max(F(s[1:]), F(s[:-1])
(当s
不是回文字符串)。求解过程采用自底向上的方法,这样就消除了重复。
在 Lisp 中,判断字符串 s
是否是回文字符串:
(string= s (reverse s))
回文字符串中又分两种,长度为奇数和偶数,分开判断代码会有重复,而 Lisp 的宏可以解决这个问题。
(defmacro increase-length (step) `(let* ((in-start (- i max-length ,step -1)) (sub (subseq s in-start (+ i 1)))) (when (string= sub (reverse sub)) (incf max-length ,step) (setf start in-start)))) (defun longest-palindrome (s) (let ((size (length s)) (start 0) (max-length 1)) (if (or (= 0 size) (string= s (reverse s))) (return-from longest-palindrome s)) (loop for i from 1 below size do (if (null (if (>= (- i max-length 1) 0) (increase-length 2))) (increase-length 1))) (subseq s start (+ start max-length))))
接触 Lisp 以来第一次实践中使用宏,挺简单的,但感觉还不错。
以上是关于动态规划与宏的主要内容,如果未能解决你的问题,请参考以下文章