keyboard wrote:
> Hi,
>
> I have a list in a file like
>
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �H
> aes ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
>
> What I want to do is to put this list in a table such that when I
> search the Chinese, it output the Pinyin.
>
> I did the following
>
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
>
> (with-open-file (is #P"GBK-1.txt" :direction :input)
> (setf *Hanzi-Pinyin-pair* (read is)))
>
> (let ((n (length *Hanzi-Pinyin-pair*)))
> (loop repeat (/ n 2)
> for i = 0 then (+ 2 i)
> do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))
>
> (defun find-pinyin (c)
> "input Chinese C to find its PINYIN"
> (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
>
> but why *hash-Hanzi-Pinyin-pair has no value?
Dunno. I tried your example, but (with my i18n settings) slime
croaked on the final gethash; so I was unable to use the hashtable,
but it seemed to have the right members. When I substituted integers
for the Chinese characters, everything worked as expected.
Maybe your lisp doesn't treat Hanzi as EQ? Try this:
(defvar *hash-Hanzi-Pinyin-pair* (make-hash-table :test 'equal))
Also, the SBCL reader is reading the Hanzi as symbols, not characters.
If yours does the same, then call (find-pinyin |��|) instead of
(find-pinyin ��).
FWIW, traversing lists by calling (elt list index) is slow; elt finds
each element by starting at the head and counting to N. Here's a few
alternatives
(defparameter *h* (make-hash-table))
(defparameter *l* '((1 2) (3 4) (5 6)))
(mapc (lambda (pair)
(setf (gethash (car pair) *h*) (cadr pair)))
*l*)
;; or
(dolist (pair *l*)
(setf (gethash (car pair) *h*) (cadr pair)))
;; or
(loop for (key val) in *l*
do (setf (gethash key *h*) val))
Or if your source list is a flat set of key/value pairs, here's
another way to walk the list:
(defparameter *h* (make-hash-table))
(loop for key = '(1 2 3 4 5 6) then (cdr val)
for val = (cdr key)
while val
do (setf (gethash (car key) *h*)
(car val)))
And I'm sure there are better alternatives.
- Daniel
keyboard wrote:
> Hi,
>
> I have a list in a file like
>
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �H
> aes ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
>
> What I want to do is to put this list in a table such that when I
> search the Chinese, it output the Pinyin.
>
> I did the following
>
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
>
> (with-open-file (is #P"GBK-1.txt" :direction :input)
> (setf *Hanzi-Pinyin-pair* (read is)))
>
> (let ((n (length *Hanzi-Pinyin-pair*)))
> (loop repeat (/ n 2)
> for i = 0 then (+ 2 i)
> do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))
FYI:
(loop for (hanzi pinyin) on *hanzi-pinyin-pair* by #'cddr
do (setf (gethash hanzi etc) pinyin))
>
> (defun find-pinyin (c)
> "input Chinese C to find its PINYIN"
> (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
>
> but why *hash-Hanzi-Pinyin-pair has no value?
Show us how you know it has no value. READ would produce symbols (which
would become the hash key and value) and you might be looking for strings.
We do not know because you stopped short of providing a full report of
your problem. It is a PITA, I know, but you really have to dump
everything into problem reports to avoid a lot of confusion and lectures
like this. :)
kt
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
ECLM rant:
http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
ECLM talk:
http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en
In article
<····································@56g2000hsm.googlegroups.com>,
keyboard <···········@gmail.com> wrote:
> Hi,
>
> I have a list in a file like
>
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �
> aes ?
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
>
> What I want to do is to put this list in a table such that when I
> search the Chinese, it output the Pinyin.
What Lisp implementation are you using?
>
> I did the following
>
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
>
> (with-open-file (is #P"GBK-1.txt" :direction :input)
> (setf *Hanzi-Pinyin-pair* (read is)))
What did it read?
> (let ((n (length *Hanzi-Pinyin-pair*)))
> (loop repeat (/ n 2)
> for i = 0 then (+ 2 i)
> do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))
Side note: above is really a horrible way to iterate over a list.
A list usually should not accessed with ELT from a LOOP.
Instead of iterating ONCE over a list, you will do it MULTIPLE
times. Lists are not arrays Common Lisp, so random access
to list elements is NOT of complexity o(1).
Use something like
CL-USER 28 : 1 > (loop for (s1 s2) on '(a b c d) by #'cddr do (print (list s1 s2)))
(A B)
(C D)
NIL
>
> (defun find-pinyin (c)
> "input Chinese C to find its PINYIN"
> (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
>
> but why *hash-Hanzi-Pinyin-pair has no value?
How do you call this function?
Note that your Lisp (when it deals with correctly with the above file)
read a list of symbols (not characters). When you use GETHASH later
make sure that you ask for a symbol (and not a character).
>
> Thank you.
--
http://lispm.dyndns.org/