2016-11-09 3 views
1

У меня есть программа lisp, которая преобразует римские цифры в десятичную форму. Он отлично работает для корректных входных данных, однако я не уверен, как проверить, является ли вход действительной римской цифрой. В настоящее время, например, при некорректном вводе («MIM»), он по-прежнему пытается его неправильно преобразовать. Мне нужно это, чтобы вместо этого вернуть сообщение ERROR. преобразование типаLISP - Проверьте конвертер римской цифры для действительной римской цифры

(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) Обратите внимание, что ' "MIM"' и ' '(MIM)' разные значения (строка против списка) , (2) Вам нужно четко указать правило, которое указывает, что делает ввод действительным или нет. Затем вы сможете добавить чеки. (3) стиль: тире-разделенные имена, нет camelCase, пожалуйста. – coredump

+0

Я знаю, что MCM действителен в течение 1900 года, то почему MIM не действует в 1999 году? – Sylwester

+0

Также обратите внимание, что формат Common Lisp уже может [печатать как римские цифры] (http://www.lispworks.com/documentation/HyperSpec/Body/22_cba.htm). –

ответ

2

Немного о стиле ...

  • данные часто нет необходимости
  • код может легко быть более общим

Пример:

(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))) 

Это означает, что вы можете использовать она со списками символов/знаков/строк, строки, векторы символов/знаков/строк:

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