challenge 文字列の反転(括弧の対応を保存)

与えられた文字列を前後反転する関数 reverseString2 を書いてください。
ただし、reverseString2 は単純に文字列を反転するのではなく、括弧の対応
を保存するようにしてください。

以前のお題で作成した単純に与えられた文字列を単純に前後反転したもの返す
reverseString では

  reverseString("文字列(もじれつ)の反転(はんてん)") 
    → ")んてんは(転反の)つれじも(列字文"

のように括弧の対応は保存されませんが、reverseString2 では

  reverseString2("文字列(もじれつ)の反転(はんてん)")
    → "(んてんは)転反の(つれじも)列字文"

のように括弧の対応が保存されます。
括弧文字は、'('と')'、'{'と'}'、'['と']'で、それぞれASCII文字と仮定し
てください。

  reverseString2("対応[の{とれている(さまざまな)括弧}の(例)]です。")
    → "。すで[(例)の{弧括(なまざまさ)るいてれと}の]応対"

入力文字列では対応の取れている括弧の内側には対応の取れない括弧文字はな
いと解釈してください。たとえば、

  reverseString2("これ(は(対応のとれていない)括弧がある例です。")
    → "。すで例るあが弧括(いないてれとの応対)は(れこ"

次のような場合は対応のとれている括弧はないという解釈になります。

  reverseString2("これ(も{対応の)とれていない}括弧の例です")
    → "。すで例の弧括}いないてれと)の応対{も(れこ"

日本語対応にする場合の文字のエンコーディングは実装側で都合のよいように
仮定してください。日本語対応であることは望ましいですが、必須ではありま
せん。 

---
このお題はnobsunさんに投稿いただきました。ご協力ありがとうございます。

Posted feedbacks - Scheme

(cons x knil)のあたりが汚いので、もうちょっと何とかなるとは思うのですが…
実行結果:
(んてんは)転反の(つれじも)列字文
。すで[(例)の{弧括(なまざまさ)るいてれと}の]応対
。すで例るあが弧括(いないてれとの応対)は(れこ
すで例の弧括}いないてれと)の応対{も(れこ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(use text.tree)

(define parens '((#\) . #\() (#\} . #\{) (#\] . #\[)))
(define openp (append (map car parens) (map cdr parens)))

(define (spl x l)
  (cond ((null? l) (values #f #f))
        ((eqv? x (car l)) (values () (cdr l)))
        ((memv (car l) openp) (values #f #f))
        (else (receive (head tail) (spl x (cdr l))
                    (values (if head (cons (car l) head) #f) tail)))))

(define (reverse-string2 l)
  (tree->string
    (fold (lambda (x knil)
            (cond ((assv x parens) =>
                   (lambda (pair)
                     (cond ((spl (cdr pair) knil)
                            (lambda (x _) x)
                            => (lambda (body rest)
                                 (cons `(,(cdr pair) ,@body ,(car pair)) rest)))
                           (else (cons x knil)))))
                  (else (cons x knil))))
          () (string->list l))))

(for-each (compose print reverse-string2)
          '("文字列(もじれつ)の反転(はんてん)"
            "対応[の{とれている(さまざまな)括弧}の(例)]です。"
            "これ(は(対応のとれていない)括弧がある例です。"
            "これ(も{対応の)とれていない}括弧の例です"))

#4300 のほぼ直訳。 パターンマッチ大好きです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(use util.match)
(use util.list)

(define PARENS (alist->hash-table '(("(" . ")")
                                    ("{" . "}")
                                    ("[" . "]"))
                                  'equal?))
(define RPARENS (alist->hash-table
                  (hash-table-map PARENS
                                  (lambda (a b) (cons b a)))
                  'equal?))

(define (reverse-string2_ str acc paren)
  (match str
         (() (cons acc '()))
         ((ch . rest)
          (cond ((hash-table-exists? PARENS ch)
                 (match-let1
                   (str_ . rest_) (reverse-string2_ rest '() ch)
                   (let1 ch_ (if (equal? ch (car str_))
                               (hash-table-get PARENS ch) ch)
                         (reverse-string2_ rest_
                                           (append str_ (list ch_) acc)
                                           paren))))
                ((and paren (hash-table-exists? RPARENS ch))
                 (let1 ch_ (if (equal? ch (hash-table-get PARENS paren))
                             (hash-table-get RPARENS ch) ch)
                       (cons (append (list ch_) acc) rest)))
                (else (reverse-string2_ rest (cons ch acc) paren))))))

(define (reverse-string2 str)
  (let1 str_ (map string (string->list str))
        (match-let1
          (reversed . _) (reverse-string2_ str_ '() #f)
          (string-join reversed ""))))

(define SAMPLES
  '(("文字列(もじれつ)の反転(はんてん)"
     "(んてんは)転反の(つれじも)列字文")
    ("対応[の{とれている(さまざまな)括弧}の(例)]です。"
     "。すで[(例)の{弧括(なまざまさ)るいてれと}の]応対")
    ("これ(は(対応のとれていない)括弧がある例です。"
     "。すで例るあが弧括(いないてれとの応対)は(れこ")
    ("これ(も{対応の)とれていない}括弧の例です。"
     "。すで例の弧括}いないてれと)の応対{も(れこ")))

(define (test-reverse-string2)
  (for-each (match-lambda
              ((input expected)
               (let* ((result (reverse-string2 input))
                      (cond_ (if (equal? expected result) 'OK 'NG)))
                 (begin
                   (format #t "(reverse-string2 ~s)\n" input)
                   (format #t "       expected: ~s\n" expected)
                   (format #t "         result: ~s" result)
                   (format #t " ... ~s\n" cond_)))))
            SAMPLES))

(define (main argv) (test-reverse-string2))

Index

Feed

Other

Link

Pathtraq

loading...