写比较字符串函数

时间:2011-06-09 20:11:02

标签: string comparison lisp common-lisp

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

我认为我会使用char函数或者您认为我必须使用subseq吗?或处理ASCII码的函数?

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

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

非常感谢!!

4 个答案:

答案 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)))))))))