2011-03-05 2 views
0

Scheme에서 생성 할 수있는 가장 투명하고 우아한 문자열 - 십진수 프로 시저 란 무엇입니까?스키마의 십진수로 문자열

'+42', '-6', '-.28'및 '496.8128'과 같은 올바른 결과가 생성되어야합니다.

이이 문제를 정수로 이전에 게시 된 목록에서 영감 : 그것은 추한 빠르고 실현 다른 사람뿐만 아니라 그것으로 재생하는 것 같아서 갔다하기 때문에

how to convert a list to num in scheme? 내가 내 첫 번째 시도를 scragged.

+0

문제는 다소 잘못 정의되어 있습니다. 법적 입력에 대한 문법을 ​​지정할 수 있습니까? –

+0

물론입니다. 나는 그것을 암시하기로했다. 선택적 선행 부호가 있습니다. 선택적 숫자가 있으며, 선택적 소수점이 있으며 선택적 추가 숫자가 있습니다. 최소한 하나의 숫자가 있어야합니다. 실제로 문법을 정의하여 여행의 재미있는 부분을 제거하지 않는 것을 선호합니다. 이 방법이 효과가 있습니까? 선택적인 'E'와 지수의 하나 이상의 숫자 추가를위한 추가 크레딧. 임의의 기본 허용을위한 추가 크레딧. 죄송합니다. 클래스가 아니며 스택 오버플로에 추가 크레딧이 없습니다. –

+0

"이것은 유효하지 않습니다. 나는 그것을 원래 잘못 포함했다. –

답변

1

매우 짧아서 결과가 소수점과 정확하게 일치하지 않으며 모든 + - 접두어를 처리합니다. 정규 표현식은 나중에 유효한 구문을 가정하는 데에만 사용됩니다.

#lang racket/base 
(require racket/match) 
(define (str->num s) 
    ;; makes it possible to assume a correct format later 
    (unless (regexp-match? #rx"^[+-]*[0-9]*([.][0-9]*)?$" s) 
    (error 'str->num "bad input ~e" s)) 
    (define (num l a) 
    (match l 
     ['() a] 
     [(cons #\. l) (+ a (/ (num l 0.0) (expt 10 (length l))))] 
     [(cons c l) (num l (+ (* 10 a) (- (char->integer c) 48)))])) 
    (define (sign l) 
    (match l 
     [(cons #\- l) (- (sign l))] 
     [(cons #\+ l) (sign l)] 
     [_ (num l 0)])) 
    (sign (string->list s))) 
+0

니스, 나는 정규 표현식 검증을 좋아한다. 나는 문제의 일반적인 계획안 해결책을 위해 포즈를 취하고 있었다. 10 진수를 정확하지 않게 만드는 것은 합리적으로 정의 된 숫자이기 때문에 잘못되었다고 생각합니다. –

+0

10 진수를 부정확하게 만드는 한 가지 이유는 Scheme 독자가 일반적으로이를 수행한다는 것입니다. 어쨌든 코드에 '0.0'이 하나 있는데, '0'으로 변경하면 항상 정확합니다. 일반적인 계획 해결책에 관해서는 - 당신은'racket' 태그를 사용했기 때문에 regexps와'match'를 사용했습니다; 후자를 없애는 것은 매우 쉽고 전자를 없애는 것은 오류 검사를 두 개의 루프로 접어서도 어렵지 않습니다. –

0

다음은 첫 번째 사진입니다. 못생긴 것이 아니라, 아름답 지 않고, 내가 원하는 것보다 더 오래갑니다. 또 하루 조정. 나는 기꺼이 해결책을 누군가의 더 나은 창조물에 전할 것입니다.

((define (string->number S) 
    (define (split L c) 
    (let f ((left '()) (right L)) 
     (cond ((or (not (list? L)) (empty? right)) (values L #f)) 
      ((eq? c (car right)) (values (reverse left) (cdr right))) 
      (else (f (cons (car right) left) (cdr right)))))) 
    (define (mkint L) 
    (let f ((sum 0) (L (map (lambda (c) (- (char->integer c) (char->integer #\0))) L))) 
     (if (empty? L) sum (f (+ (car L) (* 10 sum)) (cdr L))))) 
    (define list->num 
    (case-lambda 
     ((L) (cond ((empty? L) 0) 
       ((eq? (car L) #\+) (list->num 1 (cdr L))) 
       ((eq? (car L) #\-) (list->num -1 (cdr L))) 
       (else (list->num 1 L)))) 
     ((S L) (let*-values (((num E) (split L #\E)) ((W F) (split num #\.))) 
       (cond (E (* (list->num S num) (expt 10 (list->num E)))) 
        (F (* S (+ (mkint W) (/ (mkint F) (expt 10 (length F)))))) 
        (else (* S (mkint W)))))))) 
    (list->num (string->list S)))