2016-11-09 4 views
1

Ich habe ein Lisp-Programm, das römische Ziffern in dezimale Form umwandelt. Es funktioniert gut für gültige Eingaben, aber ich bin nicht sicher, wie man überprüft, ob die Eingabe eine gültige römische Ziffer ist. Wenn es zum Beispiel eine ungültige Eingabe ("MIM") gibt, versucht es immer noch, es falsch zu konvertieren. Ich brauche es, um stattdessen eine FEHLER-Nachricht zurückzugeben.LISP - Überprüfen römische Umrechnung für gültige römische Ziffer

(defun mapRomanToDecimal (chars nums string) 
    (loop as char across string 
     as i = (position char chars) 
     collect (and i (nth i nums)))) 

(defun parseThroughRoman (R) 
    (loop with nums = (mapRomanToDecimal "IVXLCDM" '(1 5 10 50 100 500 1000) R) 
    as (A B) on nums if A sum (if (and B (< A B)) (- A) A))) 

(defun romanToDecimal (RomanNumeral) 
    (format t "~d~%" (parseThroughRoman (numlist-to-string RomanNumeral)))) 

(defun numlist-to-string (lst) 
    (when lst 
    (concatenate 'string 
      (write-to-string (car lst)) (numlist-to-string (cdr lst))))) 


(romanToDecimal '(C D V)) -> 405 
(romanToDecimal '(M I M)) -> 1999 
+1

(1) Beachten Sie, dass ' "MIM"' und ' '(MIM)' sind verschiedene Werte (string vs Liste) . (2) Sie müssen sich über die Regel im Klaren sein, die angibt, was eine Eingabe gültig macht oder nicht. Dann können Sie Prüfungen hinzufügen. (3) stil: strich-getrennt-namen, kein camelCase, bitte. – coredump

+0

Ich weiß, MCM gilt für 1900, warum ist MIM dann nicht gültig für 1999? – Sylwester

+0

Beachten Sie auch, dass das Common-Lisp-Format bereits als römische Ziffern drucken kann (http://www.lispworks.com/documentation/HyperSpec/Body/22_cba.htm). –

Antwort

2

Ein wenig über Stil ... ist

  • Daytentypkonvertierung oft notwendig, nicht
  • Code leicht

Beispiel mehr generisch sein können:

(defvar *roman-chars* "IVXLCDM") 
(defvar *roman-nums* '(1 5 10 50 100 500 1000)) 

(defun roman-numeral-to-decimal (roman-numeral) 
    (let ((i (position (coerce roman-numeral 'character) *roman-chars*))) 
    (and i (nth i *roman-nums*)))) 

(defun map-roman-numerals-to-decimal (roman-numerals) 
    (map 'list #'roman-numeral-to-decimal roman-numerals)) 

(defun roman-to-decimal (roman) 
    (loop as (A B) on (map-roman-numerals-to-decimal roman) 
     if A sum (if (and B (< A B)) (- A) A))) 

Dies bedeutet, dass Sie verwenden können es mit Listen von Symbolen/Zeichen/Strings, Strings, Vektoren Symbole/Zeichen/Strings:

CL-USER 20 > (roman-to-decimal '(C D V)) 
405 

CL-USER 21 > (roman-to-decimal '("C" "D" "V")) 
405 

CL-USER 22 > (roman-to-decimal '(#\C#\D #\V)) 
405 

CL-USER 23 > (roman-to-decimal "CDV") 
405 

CL-USER 24 > (roman-to-decimal #(c d v)) 
405 
Verwandte Themen