我试图解决的问题是在非有向图中找到最少数量的子树,其中每个节点都在子树中。在Emacs Lisp中,如何获得单个散列键?
我的算法如下:
make a hash as follows
key= each node,
value= all nodes directly accessible from the key node
if a node has no edges it still has a key/value pair in the hash
each edge will be represented twice, once each direction
loop until hash is empty
get any hash key/value pair
save the value to the working-list
remove the key/value from the hash
in a loop until the working-list is empty
(when (gethash (car working-list) hash)
concatenate value to the end of the working-list
(remhash (car working-list) hash))
(pop working-list)
When the loop is finished you have removed all nodes and edges in a single subtree from the hash.
Increment number of subtrees.
end loop until the hash is empty.
report number of subtrees
下面的代码:
(defun count-subtrees (hash)
; hash
; key= each node,
; value= all nodes directly accessible from the key node
; if a node has no edges it still has a key/value pair in the hash
; each edge will be represented twice, once each direction
(let ((number-of-trees 0))
(while (setf key (anykey-in-hash hash)) ; this is where I need any key in the hash
(setf working-list (gethash key hash))
(remhash key hash)
(while (gethash (car working-list) hash)
(setf working-list (append working-list
(gethash (car working-list hash))))
(remhash (car working-list) hash)
(pop working-list))
(incf number-of-trees))
number-of-trees))
我不想遍历键,我想只有一个。
备注:
谢谢大家的回复。我正在将这些评论引导给你。
编辑改变了我的问题,添加了“随机”一词。我不在乎它是否随机。回应:
(defun anykey-in-hash (hash-table)
(block nil
(maphash (lambda (k v) (return (values k v)))
是一个完美的解决方案。
我无意中使用'while'(我从Paul Graham的书中得到)而没有定义它。我希望它不会让任何人感到困惑。
我也用setf代替let来定义变量。愚蠢的错误,我永远不会真的这样做。
最初我有一个所有键的列表。但在算法期间,键/值对被删除。这就是为什么我需要留下任何一个。
我也使用工作列表作为列表。工作列表包含子树中的一些节点。所有这些节点(以及他们的孩子*和他们孩子的孩子......)都需要从哈希中删除。追加到这个列表是为了简化代码。在实际的应用程序中,我会使用其他数据结构,可能是列表的列表。但我觉得这样做会增加复杂性,而不会增加任何问题的含义。
*当我说孩子,我的意思是使用节点作为散列的关键,值是一个孩子的列表。
追加到列表的末尾并不是很快,尤其是如果列表很长... –
*我无意中使用了'while'(我从Paul Graham的书中得到)而没有定义它*:我们该怎么做使用标签吗?保持emacs-lisp或更改为common-lisp? – coredump
我不在乎它是否是“Emacs Lisp”。其他人从“Lisp”改变了这个问题 –