LISP递归作业求助:实现字符串与北约音标双向转换
Hey there, let's work through these recursion-only LISP functions—no loops, no variables, just cons and recursive traversal. I've been there staring at nested lists wondering how to break it down, so let's take this step by step.
1. Converting Abbreviation Lists to NATO Phonetic Format (((PRO)(LAN)) → "PapaRomeoOscar LimaAlfaNovember")
The core idea here is recursive decomposition: we'll handle three levels of structure:
- Individual characters → NATO phonetic strings
- Single symbol (like
PRO) → concatenated NATO string - Outer list of symbols → space-separated full phrase
First, let's write a recursive helper to map characters to their NATO equivalents (we'll use cond for pattern matching, no variables involved):
(defun char-to-nato (c) (cond ((equal c #\P) "Papa") ((equal c #\R) "Romeo") ((equal c #\O) "Oscar") ((equal c #\L) "Lima") ((equal c #\A) "Alfa") ((equal c #\N) "November") ;; Extend with other letters as needed ))
Next, convert a single symbol (like PRO) to its NATO string. We'll avoid variables by directly operating on the symbol's string representation, recursively processing each character:
(defun str-to-nato (str) (if (string= str "") "" (concatenate 'string (char-to-nato (char str 0)) (str-to-nato (subseq str 1))))) (defun word-to-nato (sym) (str-to-nato (string sym)))
Finally, process the outer list of symbols. We recursively handle the first element, then combine it with the result of processing the rest of the list (adding a space between words):
(defun list-to-nato (lst) (cond ((null lst) "") ((null (rest lst)) (word-to-nato (first lst))) (t (concatenate 'string (word-to-nato (first lst)) " " (list-to-nato (rest lst))))))
Test it with your input:
(list-to-nato '((PRO)(LAN))) ; Returns "PapaRomeoOscar LimaAlfaNovember"
2. Converting NATO Phonetic Lists Back to Lowercase Abbreviations (((PapaRomeoOscar)(LimaAlfaNovember)) → "pro lan")
This reverse problem uses similar recursive logic, but now we're matching prefixes of the NATO string to map back to characters, then building lowercase words.
First, a helper to match NATO string prefixes and return the corresponding character plus the remaining string (we use cons here to pair two values without variables):
(defun nato-to-char (str) (cond ((string= (subseq str 0 4) "Papa") (cons #\P (subseq str 4))) ((string= (subseq str 0 5) "Romeo") (cons #\R (subseq str 5))) ((string= (subseq str 0 5) "Oscar") (cons #\O (subseq str 5))) ((string= (subseq str 0 4) "Lima") (cons #\L (subseq str 4))) ((string= (subseq str 0 4) "Alfa") (cons #\A (subseq str 4))) ((string= (subseq str 0 8) "November") (cons #\N (subseq str 8))) ;; Extend with other NATO terms as needed ))
Next, recursively process a full NATO string into a list of characters. We avoid variables by directly nesting the nato-to-char call to get both the character and remaining string:
(defun nato-str-to-chars (str) (if (string= str "") nil (cons (car (nato-to-char str)) (nato-str-to-chars (cdr (nato-to-char str))))))
Convert the character list to a lowercase word:
(defun chars-to-word (chars) (string-downcase (coerce chars 'string)))
Finally, process the outer list of NATO strings into a space-separated lowercase phrase:
(defun nato-list-to-words (lst) (cond ((null lst) "") ((null (rest lst)) (chars-to-word (nato-str-to-chars (first lst)))) (t (concatenate 'string (chars-to-word (nato-str-to-chars (first lst))) " " (nato-list-to-words (rest lst))))))
Test it with your input:
(nato-list-to-words '("PapaRomeoOscar" "LimaAlfaNovember")) ; Returns "pro lan"
Key Notes on Recursion & Cons
- Every function follows the recursive pattern: handle the base case (empty list/string), then process the first element and recurse on the rest.
- We use
consto pair values (like character + remaining string) without needing to define variables, which aligns with your initial idea of leaning into cons operations.
内容的提问来源于stack exchange,提问作者Evan Ross

