我应该找到从根到LISP中给定节点的路径。最好使用纯功能方法。
二叉树表示使用子列表,例如:
(A (B) (C (D) (E)))
- A是根,B是A的左子,C是A的右子,D是C的左子,E是C的右子。
在我看来,应该有一些方法可以避免重复以下函数调用:
(get-path (cadr l) x)
(get-path (caddr l) x)
我是LISP的新手并且我不知道并且似乎无法找到解决方案,但我认为必须有一种纯粹的功能性方法。也许使用lambdas?但不确定如何。我使用了错误的方法吗?任何形式的帮助都非常感谢。
;;; l is the list with the binary tree
;;; x is the node we are looking for
(defun get-path(l x)
(cond
;; nothing to search for anymore
((null l) nil)
;; found the node we were looking for
;; in this case we return a list containing only x
((equal (car l) x) (list x))
;; the node was found on the left branch
((not(equal (get-path (cadr l) x) nil))
(cons (car l) (get-path (cadr l) x)))
;; the node was found on the right branch
((not(equal (get-path (caddr l) x) nil))
(cons (car l) (get-path (caddr l) x)))))
答案 0 :(得分:4)
这个怎么样?
one = True
two = False
three = False
typed_input = raw_input("Type here: ")
#first
if one == True and two == False and three == False:
if typed_input == "blah":
do something
typed_input = raw_input("Type here: ")
one = False
two = True
three = False
elif "the" in typed_input:
do something else
typed_input = raw_input("Type here: ")
one = False
two = True
three = False
你甚至应该定义有意义的命名函数,比如(defun root-path (tree element)
(when tree
(cons (first tree)
(unless (eql (first tree) element)
(or (root-path (second tree) element)
(root-path (third tree) element)
(return-from root-path nil))))))
tree-value
和left-subtree
,但这可能是矫枉过正的。
在上文中,请注意right-subtree
(resp。when
)在条件失败时(resp。成功)用于其unless
值。如果您愿意,可以使用nil
或cond
表达式进行翻译。这里唯一的重复是双if
值,可以由编译器优化,也可以使用周围的(first tree)
绑定进行手动优化。
原始代码无效。解决方案是使用Joshua的答案,但我不会复制粘贴在这里,所以我添加了let
表达式。虽然它有效,但您的老师和/或同事可能不喜欢这种方法; - )
return-from
答案 1 :(得分:3)
我结合了最后两个cond条款。你想检查左侧,看看那里是否有路径,如果有路径,请抓住它,如果没有,请检查右侧。然后,无论哪一个产生路径(如果有的话),你想要追加到那个。这看起来像这样。首先,为方便起见,有两个功能:
(defun element (tree)
(first tree))
(defun left (tree)
(second tree))
(defun right (tree)
(third tree))
现在,解决方案的真正含义是:
(defun get-path (element tree)
(cond
;; A null tree is empty and doesn't match anything.
((null tree) '())
;; If the element of this tree is the element, then we have a
;; partial path of length 1: (ELEMENT).
((eql element (element tree)) (list element))
;; Othweise, let PATH be the path on the left or the path on the
;; right, whichever exists.
(t (let ((path (or (get-path element (left tree))
(get-path element (right tree)))))
;; If there's no path on either side, then return NIL.
;; Otherwise, prepend the current element onto the path that
;; exists.
(if (null path) '()
(list* (element tree) path))))))
请注意,列表* 与缺点的功能相同,但它更清楚地表明您正在使用列表,不只是 cons cells 。您也可以使用缺点。
我们可以确认这是按预期工作的:
(defparameter *tree* '(A (B) (C (D) (E))))
(get-path 'c *tree*) ;;=> (A C)
(get-path 'd *tree*) ;;=> (A C D)
(get-path 'f *tree*) ;;=> NIL
答案 2 :(得分:2)
将labels
用于内部(本地)功能:
(defun get-path(l x)
(labels ((prepend-path (elt)
(cons (car l) (get-path elt x))))
(cond
;; nothing to search for anymore
((null l) nil)
;; found the node we were looking for
;; in this case we return a list containing only x
((equal (car l) x) (list x))
;; the node was found on the left branch
((not(equal (get-path (cadr l) x) nil))
(prepend-path (cadr l)))
;; the node was found on the right branch
((not(equal (get-path (caddr l) x) nil))
(prepend-path (caddr l))))))
或者,您可以使用flet
代替labels
,因为您没有相互引用的内部函数。就个人而言,我使用labels
并且因为这个原因几乎没有使用flet
(加上重新缩进函数的开销。)
答案 3 :(得分:0)
你可以做的是从Common Lisp中的TXR Lisp复制照应conda
和ifa
宏。 (源代码在这里;祝你好运!)enter link description here
然后您可以这样写,使用照应get-path
变量引用it
表达式。
(conda
;; nothing to search for anymore
((null l) nil)
;; found the node we were looking for
;; in this case we return a list containing only x
((equal (car l) x) (list x))
;; the node was found on the left branch
((not (equal (get-path (cadr l) x) nil)) (cons (car l) it))
;; the node was found on the right branch
((not (equal (get-path (caddr l) x) nil)) (cons (car l) it)))
conda
对于(not x)
和(null x)
(TXR Lisp中的(false x)
)表达式非常聪明。如果测试表达式是其中之一,那么它会递归到x
执行#34; anaphoric it
"。
请注意,it
绑定到地方,而不仅仅是值。 it
的目标不仅不会被评估多次,如果目标是一个地方,那么it
指的是那个地方:
(ifa (< x 10)
(inc it)) ;; increments x.
ifa
的这个方面是在placelet
宏的帮助下实现的,它在Common Lisp中不存在。快速而肮脏的替代方法是使用symbol-macrolet
。唯一的问题是表示地点的符号宏允许对地点进行多次评估,而placelet
只评估一次地点。然后,生成的词汇符号表示存储位置,而不是整体表达式。
ifa
旨在与保罗格雷厄姆aif
擦拭地板,或者补充它; conda
基于ifa
。(not (equal whatever nil))
。
顺便说一下,不要写像
这样的表达式equal
在Lisp中!首先,如果您与nil
进行比较,nil
平等并不是特别有意义;只有equal
为nil
到eq
,并且这是根据(not (eq whatever nil))
相等,所以您可能会:{/ p>
eq
其次,对于不是(if (not (eq foo nil)) do-this) ---same-as--> (if foo do-this)
到nil的东西意味着某事是真的。也就是说:
aif
<!/ P>
如果我们重构你的代码以摆脱这些东西,那么如果acond
(和基于它的(ifa (not (equal (get-path whatever) nil))) (list it))
我们有保罗格雷厄姆风格的照应,那就更好了)。也就是说:
(aif (get-path whatever) (list it))
变为:
it
其中ifa
通常是整个测试表达式的值,而不是那个表达式中有点巧妙选择的成分。
在(ifa (true (get-path whatever)) (list it))
下,使用以下内容表达的更为详细:
true
(defun true (x) (identity x)).
可以定义为
ifa
如果没有额外的换行,it
会将whatever
绑定到org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms. Firefox console output:
ddons.xpi DEBUG checkForChanges
1450818781417 addons.xpi DEBUG Loaded add-on state from prefs: {"app-profile":{"fxdriver@googlecode.com":{"d":"C:\\Users\\sluite\\AppData\\Local\\Temp\\anonymous4238069008057039774webdriver-profile\\extensions\\fxdriver@googlecode.com","e":false,"v":"2.45.0","st":1450818779415,"mt":1450818779275}},"app-global":{"{972ce4c6-7e08-4474-a285-3208198ce6fd}":{"d":"C:\\Program Files (x86)\\Mozilla Firefox\\browser\\extensions\\{972ce4c6-7e08-4474-a285-3208198ce6fd}","e":true,"v":"43.0.1","st":1450741870041,"mt":1450322003000}}}
1450818781418 addons.xpi DEBUG Existing add-on fxdriver@googlecode.com in app-profile
1450818781418 addons.xpi DEBUG getModTime: Recursive scan of {972ce4c6-7e08-4474-a285-3208198ce6fd}
1450818781419 addons.xpi DEBUG Existing add-on {972ce4c6-7e08-4474-a285-3208198ce6fd} in app-global
1450818781419 addons.xpi DEBUG getInstallState changed: false, state: {"app-profile":{"fxdriver@googlecode.com":{"d":"C:\\Users\\sluite\\AppData\\Local\\Temp\\anonymous4238069008057039774webdriver-profile\\extensions\\fxdriver@googlecode.com","e":false,"v":"2.45.0","st":1450818779415,"mt":1450818779275}},"app-global":{"{972ce4c6-7e08-4474-a285-3208198ce6fd}":{"d":"C:\\Program Files (x86)\\Mozilla Firefox\\browser\\extensions\\{972ce4c6-7e08-4474-a285-3208198ce6fd}","e":true,"v":"43.0.1","st":1450741870041,"mt":1450322003000}}}
1450818781420 addons.xpi DEBUG No changes found
1450818781426 addons.manager DEBUG Registering shutdown blocker for XPIProvider
1450818781426 addons.manager DEBUG Provider finished startup: XPIProvider
1450818781426 addons.manager DEBUG Starting provider: LightweightThemeManager
1450818781426 addons.manager DEBUG Registering shutdown blocker for LightweightThemeManager
1450818781427 addons.manager DEBUG Provider finished startup: LightweightThemeManager
1450818781427 addons.manager DEBUG Starting provider: GMPProvider
1450818781431 addons.manager DEBUG Registering shutdown blocker for GMPProvider
1450818781431 addons.manager DEBUG Provider finished startup: GMPProvider
1450818781431 addons.manager DEBUG Starting provider: PluginProvider
1450818781431 addons.manager DEBUG Registering shutdown blocker for PluginProvider
1450818781432 addons.manager DEBUG Provider finished startup: PluginProvider
1450818781432 addons.manager DEBUG Completed startup sequence
1450818781497 addons.xpi-utils DEBUG Starting async load of XPI database C:\Users\sluite\AppData\Local\Temp\anonymous4238069008057039774webdriver-profile\extensions.json
*** Blocklist::_loadBlocklistFromFile: blocklist is disabled
1450818781568 addons.manager DEBUG Starting provider: <unnamed-provider>
1450818781568 addons.manager DEBUG Registering shutdown blocker for <unnamed-provider>
1450818781568 addons.manager DEBUG Provider finished startup: <unnamed-provider>
1450818781653 addons.xpi-utils DEBUG Async JSON file read took 0 MS
1450818781653 addons.xpi-utils DEBUG Finished async read of XPI database, parsing...
1450818781653 addons.xpi-utils DEBUG Successfully read XPI database
1450818781711 addons.manager DEBUG Starting provider: PreviousExperimentProvider
1450818781711 addons.manager DEBUG Registering shutdown blocker for PreviousExperimentProvider
1450818781712 addons.manager DEBUG Provider finished startup: PreviousExperimentProvider
1450818825183 addons.manager DEBUG shutdown
1450818825183 addons.manager DEBUG Calling shutdown blocker for XPIProvider
1450818825184 addons.xpi DEBUG shutdown
1450818825184 addons.xpi-utils DEBUG shutdown
1450818825184 addons.manager DEBUG Calling shutdown blocker for LightweightThemeManager
1450818825184 addons.manager DEBUG Calling shutdown blocker for GMPProvider
1450818825185 addons.manager DEBUG Calling shutdown blocker for PluginProvider
1450818825186 addons.manager DEBUG Calling shutdown blocker for <unnamed-provider>
1450818825187 addons.manager DEBUG Calling shutdown blocker for PreviousExperimentProvider
1450818825189 addons.xpi DEBUG Notifying XPI shutdown observers
1450818825191 addons.manager DEBUG Async provider shutdown done
at org.openqa.selenium.firefox.internal.NewProfileExtensionConnection.start(NewProfileExtensionConnection.java:118)
at org.openqa.selenium.firefox.FirefoxDriver.startClient(FirefoxDriver.java:246)
at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:114)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:193)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:186)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:182)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:95)
at WindowsHandle.HandleACLPopUP.baseURL(HandleACLPopUP.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.TestRunner.beforeRun(TestRunner.java:641)
at org.testng.TestRunner.run(TestRunner.java:609)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
。