我完全理解在lisp中使用list但我在使用string时遇到了问题。 我尝试编写自己的函数代码,如string>或字符串<从常见的lisp了解lisp如何处理字符串。 例如,abcde大于abbb并返回1.
我认为我会使用char函数或者您认为我必须使用subseq吗?或处理ASCII码的函数?
以下是我发现的案例: - 每个字符串的字符0相等,我们继续使用下一个字符。 -charactere 0是不同的,一个比另一个小,我们停止。
我需要有关“转到下一个角色”的帮助。
非常感谢!!
答案 0 :(得分:2)
这是Common Lisp版本。您可以使用ELT,因为
(type-of "a") => (SIMPLE-ARRAY CHARACTER (1))
(defun my-string< (a b &key (start 0))
(cond
((= start (length a) (length b))
nil)
((>= start (min (length a) (length b)))
(error "Undefined"))
((char= (elt a start) (elt b start))
(my-string< a b :start (1+ start)))
((char< (elt a start) (elt b start))
t)))
答案 1 :(得分:1)
这是一个函数的实现,给定两个字符串将返回-1,0或+1,具体取决于第一个是小于,等于还是大于第二个。 如果一个字符串是另一个字符串的初始部分,那么较短的字符串被认为是“小于”更长的字符串。
算法很简单...循环每个char,直到索引超过其中一个字符串或者发现字符不同。
(defun strcmp (a b)
(do ((i 0 (1+ i))
(na (length a))
(nb (length b)))
((or (= i na) (= i nb) (char/= (elt a i) (elt b i)))
(cond
((= i na nb) 0) ;; Strings are identical
((= i na) -1) ;; a finished first
((= i nb) 1) ;; b finished first
((char< (elt a i) (elt b i)) -1) ;; Different char a < b
(t 1))))) ;; Only remaining case
(defun test (a b)
(format t "(strcmp ~s ~s) -> ~s~%"
a b (strcmp a b)))
(test "abc" "abc")
(test "ab" "abc")
(test "abc" "ab")
(test "abd" "abc")
(test "abc" "abd")
输出
(strcmp "abc" "abc") -> 0
(strcmp "ab" "abc") -> -1
(strcmp "abc" "ab") -> 1
(strcmp "abd" "abc") -> 1
(strcmp "abc" "abd") -> -1
答案 2 :(得分:1)
你的问题已经解决,但万一遇到别人, 以下方法可能有用:
我从源代码安装了SBCL并保留了源代码。 这允许我运行M-。在函数名称上,如string&lt; 它将跳转到你的lisp实现中的定义。
在我的情况下,我最终得到了这个宏:
;;; LESSP is true if the desired expansion is for STRING<* or STRING<=*.
;;; EQUALP is true if the desired expansion is for STRING<=* or STRING>=*.
(sb!xc:defmacro string<>=*-body (lessp equalp)
(let ((offset1 (gensym)))
`(with-two-strings string1 string2 start1 end1 ,offset1 start2 end2
(let ((index (%sp-string-compare string1 start1 end1
string2 start2 end2)))
(if index
(cond ((= (the fixnum index) (the fixnum end1))
,(if lessp
`(- (the fixnum index) ,offset1)
`nil))
((= (+ (the fixnum index) (- start2 start1))
(the fixnum end2))
,(if lessp
`nil
`(- (the fixnum index) ,offset1)))
((,(if lessp 'char< 'char>)
(schar string1 index)
(schar string2 (+ (the fixnum index) (- start2 start1))))
(- (the fixnum index) ,offset1))
(t nil))
,(if equalp `(- (the fixnum end1) ,offset1) nil))))))
) ; EVAL-WHEN
答案 3 :(得分:0)
在Scheme中没有带字符串的迭代(“next”)的直接概念。这仅适用于列表。因此,您必须使用索引进行迭代:
(define (string<? lhs rhs)
(let* ((lhslen (string-length lhs))
(rhslen (string-length rhs))
(minlen (min lhslen rhslen)))
(let loop ((i 0))
(if (= i minlen) (< lhslen rhslen)
(let ((lhschar (string-ref lhs i))
(rhschar (string-ref rhs i)))
(cond ((char<? lhschar rhschar) #t)
((char<? rhschar lhschar) #f)
(else (loop (+ i 1)))))))))