String 写比较字符串函数

String 写比较字符串函数,string,comparison,lisp,common-lisp,String,Comparison,Lisp,Common Lisp,我完全理解lisp中list的用法,但我在使用string时遇到了问题。 我试图从CommonLisp编写自己的函数代码,如string>或string(简单数组字符(1)) (取消我的字符串=起点(最小(长度a)(长度b))) (错误“未定义”)) ((字符=(英语教学a开始)(英语教学b开始)) (我的字符串

我完全理解lisp中list的用法,但我在使用string时遇到了问题。 我试图从CommonLisp编写自己的函数代码,如string>或string<,以了解lisp如何处理字符串。 例如,abcde比abbb大,返回1

我想我会使用char函数,还是你认为我必须使用subseq?还是处理ASCII码的函数

以下是我发现的案例: -每个字符串的字符0都相等,我们继续下一个字符。 -字符0不同,一个比另一个小,我们停止

我需要关于“转到下一个角色”的帮助


非常感谢

在Scheme中,没有直接的字符串迭代(“下一步”)概念。这只适用于列表。因此,您必须使用索引进行迭代:

(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)))))))))

(define(string这是常见的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)))
(a的类型)=>(简单数组字符(1))
(取消我的字符串<(a键和b键(开始0))
(续)
(=起点(长度a)(长度b))
零)
((>=起点(最小(长度a)(长度b)))
(错误“未定义”))
((字符=(英语教学a开始)(英语教学b开始))
(我的字符串
这是一个函数的实现,给定两个字符串将返回-1、0或+1,具体取决于第一个字符串是小于、等于还是大于第二个字符串。 如果一个字符串是另一个字符串的初始部分,则认为较短的字符串“小于”较长的字符串

算法非常简单…循环每个字符,直到索引超过其中一个字符串,或者如果发现一个字符不同

(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")

你的问题已经解决了,但万一你遇到其他人, 以下方法可能有用:

我从源代码处安装了SBCL,并保留源代码。 这允许我在函数名(比如字符串)上运行M-< 它将跳转到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

;;如果所需的扩展是用于STRINGOh哇,失败。我没有意识到这个问题是一个[common lisp]问题,而不是[scheme]问题。无论如何,我会继续用它来说明原理。谢谢!我开始理解它是如何工作的。但我有问题理解:“start”和Min和我在LISP文档中没有发现。<代码> min <代码>只是一个数字最小值,即返回其最小的参数。<代码>:开始< /代码>是一个关键字参数。
?START是一个关键字参数。它的目的是允许在字符串中的任何位置启动谓词。我不确定参数对我的字符串调用方的有用性函数MIN是在公共Lisp Hyperspec中定义的。可以在这里找到:MIN的定义在这里谢谢!我了解它的工作原理。Last问题:“na”和“nb”是什么(第3/4行),如果我是对的,它们包含(长度a)和(长度b)的值?
;;; 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