← Архив: Common Lisp

Строковые ключи в hash-таблице

Author: · 29.12.2011 15:07
· original author: Lighten
В стандартном common lisp, функция gethash принимает в качестве аргумента символ. Но символы ограничены на некоторые буквы и знаки. А мне нужны они все. Попробовал вводить в качестве ключа строки, ошибки не выдал, но по запросу соответствующее значение не возвращает, а просто nil. При выводе всех ключей и соответствующих значений всё нормально, значение есть и оно не nil. Но нужен-то не полный перебор, а доступ по ключу!!! А заменять знаки, которые допустимы в символах и потом их переводить... лучше свой хэш написать))) Вопрос - есть ли способ работать с хэшем со строковым ключом, или какую какую библиотеку подскажите, пожалуйста.
PS: Использую SBCL+emacs+SLIME.
· original author: lithp
(make-hash-table :test #'equal)
· original author: bach74
смотрите через Slime по комбинации C-c C-d h значение make-hash-table в hyperspec прежде чем задаете вопросы
 Function MAKE-HASH-TABLE
Syntax:
make-hash-table &key test size rehash-size rehash-threshold => hash-table
Arguments and Values:
test---a designator for one of the functions eq, eql, equal, or equalp. The default is eql.
size---a non-negative integer. The default is implementation-dependent.
rehash-size---a real of type (or (integer 1 *) (float (1.0) *)). The default is implementation-dependent.
rehash-threshold---a real of type (real 0 1). The default is implementation-dependent.
hash-table---a hash table.
Description:
Creates and returns a new hash table.
test determines how keys are compared. An object is said to be present in the hash-table if that object is the same under the test as the key for some entry in the hash-table.
size is a hint to the implementation about how much initial space to allocate in the hash-table. This information, taken together with the rehash-threshold, controls the approximate number of entries which it should be possible to insert before the table has to grow. The actual size might be rounded up from size to the next `good' size; for example, some implementations might round to the next prime number.
rehash-size specifies a minimum amount to increase the size of the hash-table when it becomes full enough to require rehashing; see rehash-theshold below. If rehash-size is an integer, the expected growth rate for the table is additive and the integer is the number of entries to add; if it is a float, the expected growth rate for the table is multiplicative and the float is the ratio of the new size to the old size. As with size, the actual size of the increase might be rounded up.
rehash-threshold specifies how full the hash-table can get before it must grow. It specifies the maximum desired hash-table occupancy level.
The values of rehash-size and rehash-threshold do not constrain the implementation to use any particular method for computing when and by how much the size of hash-table should be enlarged. Such decisions are implementation-dependent, and these values only hints from the programmer to the implementation, and the implementation is permitted to ignore them.
Examples:
(setq table (make-hash-table)) => #<HASH-TABLE EQL 0/120 46142754> (setf (gethash "one" table) 1) => 1 (gethash "one" table) => NIL, false (setq table (make-hash-table :test 'equal)) => #<HASH-TABLE EQUAL 0/139 46145547> (setf (gethash "one" table) 1) => 1 (gethash "one" table) => 1, T (make-hash-table :rehash-size 1.5 :rehash-threshold 0.7) => #<HASH-TABLE EQL 0/120 46156620>
Affected By: None.
Exceptional Situations: None.
See Also:
gethash, hash-table
Notes: None.
· original author: bach74
там даже примеры со стрингами есть.  Кроме того, есть масса другой литературы. Ее легко скачать.
· original author: andy128k
* (intern "Ну?
И каких символов не хватает?
!№;%:?*()~@#$%^&|/\\")
|Ну?
И каких символов не хватает?
!№;%:?*()~@#$%^&\|/\\|
NIL
*
· original author: Lighten
Спасибо большое!
· original author: Lighten
благодарю, на emacs и slime только перешёл, с emacs'ом вообще на "вы", из книг пока только PCL, Paradigms of Artificail intelligence и Land of Lisp выдержками почитал, искал в них, возможно пропустил... Про intern знаю, но не знаю как его правильно применить скажем вот к такому связыванию:
(setf (intern "Сколько будет дважды два?")
(intern "Сам считай!")
)

чтобы получилось: 
REPL
> Сколько будет дважды два?
>Сам считай!
· original author: Lighten
Разве что так:
(eval (list 'setf (intern "Сколько будет дважды два?") "Сам считай!"))
(eval (intern (read-line)))
Короче, спасибо всем, кто помог лучше познать lisp!! Буду дальше стараться!
· original author: lithp
CL-USER 1 > (setf (symbol-value (intern "Сколько будет дважды два?"))
                  (intern "Сам считай!")
)

Сам\ считай!
CL-USER 2 > |Сколько будет дважды два?|
Сам\ считай!