私が解決しようとしている問題は、各ノードがサブツリーにある非有向グラフで、最も少ない数のサブツリーを見つけることです。Emacs Lispでは、どのようにして1つのハッシュキーを取得しますか?
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))
私はキーを反復処理する必要はありませんが、私は1を取得したい
私のアルゴリズムは次のようです。
注:
ありがとうございます。私はあなたにこれらのコメントを指示しています。
エディタが私の質問を変更し、「ランダムに」という言葉を追加しました。ランダムであるかどうかは気にしない。応答:
(defun anykey-in-hash (hash-table)
(block nil
(maphash (lambda (k v) (return (values k v)))
は完璧な解決策です。
「私はポール・グラハムの本から得たもの」を間違いなく定義していませんでした。私は誰もそれを混乱させないことを願っています。
また、letの代わりにsetfを使って変数を定義しました。愚かな間違い、私は本当にそれを行うことはありません。
最初はすべてのキーのリストがあります。しかしアルゴリズムの間に、キーと値のペアは削除されます。だからこそ私は誰かを残す必要があるのです。
私もリストとしてワーキングリストを使用しています。作業リストには、サブツリー内のいくつかのノードが含まれています。これらのノード(およびその子*およびその子の子供...)のすべてをハッシュから削除する必要があります。このリストに追加することは、コードを簡素化することでした。実際のアプリケーションでは、他のデータ構造、おそらくリストのリストを使用します。しかし、ここでそうすることは、質問の意味に何も追加せずに複雑さを増すことになると感じました。
*私が子供と言うとき、私はハッシュのキーとしてノードを使うことを意味します、値は子供のリストです。
リストが非常に長い場合は、特にリストが非常に長い場合は、特にスピードが遅くなりません。 –
*私は誤って 'while'を使用しました(私はPaul Grahamの本から得ました)。タグとは? emacs-lispを保つか、common-lispに変更しますか? – coredump
"Emacs Lisp"であれば気にしません。他の誰かが "Lisp"から質問を変更しました –