用scheme實現KMP算法

scheme真喪心病狂

形式語義學作業,自選函數式語言實現任意程序。於是選了scheme。不得不說這個語言真蛋疼,括號匹配導致我檢查的時間趨近於正無窮。

#lang racket

(define f (make-vector 101))
(define m 7)
(define n 7)

(define loop2
  (lambda(P i j)
    (begin
      (if(and (> j 0) (not (eqv? (string-ref P i) (string-ref P j))))
         (loop2 P i (vector-ref f j))
         j)
      )))

(define (getfail P)
  (set! m (string-length P))
  (vector-set! f 0 0)
  (vector-set! f 1 0)
  (define loop
    (lambda(i)
      (if(< i m)
         (begin
           (set! i (+ i 1))
           (let ((j (loop2 P (- i 1) (vector-ref f (- i 1)))))
             (if(eqv? (string-ref P (- i 1)) (string-ref P j))
                (vector-set! f i (+ j 1))
                (vector-set! f i 0)))
           (loop i))
         0)))
  (loop 1))

(define loop3
  (lambda(P T i j)
    (begin
      (if(and (> j 0) (not (eqv? (string-ref T i) (string-ref P j))))
         (loop3 P T i (vector-ref f j))
         j)
      )))

(define (KMP T P)
  (getfail P)
  (set! n (string-length T))
  (define loop
    (lambda(i j)
      (if(and (< i n) (< j m))
         (begin
           (set! i (+ i 1))
           (set! j (loop3 P T (- i 1) j))
           (when(eqv? (string-ref T (- i 1)) (string-ref P j))
             (set! j (+ j 1)))
           (loop i j))
      (cons i j)) ))
(loop 0 0))

(define ans (cons -1 -1))

(define (main)
  (let ((P (read)))
    (when(not(eof-object? P))
      (getfail P)
      (define loop
        (lambda(i)
          (if(< i m)
             (begin
               (display (vector-ref f i))
               (display " ")
               (loop (+ i 1)))
             (newline))))
      (loop 0)
      (main))))

(define loopp
  (lambda(T i)
    (if(< i n)
       (begin
         (if(and (>= i (- (car ans) m)) (< i (car ans)))
            (display (char-upcase (string-ref T i)))
            (display (string-ref T i)))
         (loopp T (+ i 1)))
       (newline))))

(define (main2)
  (display "請依次輸入模式串和匹配串:")
  (let ((P (read)) (T (read)))
        (when(not(eof-object? P))
          (set! ans (KMP T P))
          (define loop
            (lambda(i)
              (if(< i m)
                 (begin
                   (display (vector-ref f i))
                   (display " ")
                   (loop (+ i 1)))
                 (newline))))
          (loop 0)
          (display ans)
          (newline)
          (if(= (cdr ans) m)
             (begin
               (display "匹配成功,顯示如下:")
               (loopp T 0))
             (begin
               (display "匹配失敗,匹配串中不包含模式串。")
               (newline)))
             (main2))))


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章