LISP新手请求逐行解析count-lower-case-vowels函数:do循环与赋值语句疑问
count-lower-case-vowels First, let's restate your code with proper formatting for readability:
(defun count-lower-case-vowels (str) (do ((i 0 (1+ i)) (acc 0) (len (length str))) ((= i len) acc) (when (or (equal (aref str i) #\a) (equal (aref str i) #\e) (equal (aref str i) #\i) (equal (aref str i) #\o) (equal (aref str i) #\u)) (:= acc (1+ acc)))))
1. Function Definition
(defun count-lower-case-vowels (str))
This defines a new function named count-lower-case-vowels that accepts one parameter: str (the input string we want to scan for lowercase vowels).
2. The do Loop: Core Iteration Logic
The do loop in Common Lisp is a flexible iteration tool with this structure:(do (variable-initializations) (end-condition return-value) loop-body)
Let’s break down each part of your do loop:
Variable Initialization Block
((i 0 (1+ i)) (acc 0) (len (length str)))
Each line defines a loop variable with up to three components: name, starting value, and update step (run at the end of each iteration):
i 0 (1+ i):istarts at0(our starting index for traversing the string).- After every loop iteration,
iincrements by 1 ((1+ i)is shorthand for(+ i 1)).
acc 0:acc(short for "accumulator") starts at0—this tracks how many lowercase vowels we’ve found.- No update step here means
accwon’t change automatically; we have to modify it manually when we find a match.
len (length str):lenis set to the length ofstronce, at the start of the loop.- No update step keeps
lenconstant—it’s our stopping point (when we’ve checked every character in the string).
End Condition & Return Value
((= i len) acc)
This is the loop’s exit rule:
- When
iequalslen(we’ve reached the end of the string), the loop stops. - The function returns
acc—the total count of lowercase vowels found.
3. The when Block: Vowel Check & Count Update
Inside the do loop, the when statement runs only if its condition is true:
(when (or (equal (aref str i) #\a) (equal (aref str i) #\e) (equal (aref str i) #\i) (equal (aref str i) #\o) (equal (aref str i) #\u)) (:= acc (1+ acc)))
Let’s unpack this:
(aref str i):aref(array reference) grabs the character at indexifrom the stringstr(strings in Common Lisp are arrays of characters).#\a: This is the character literal for lowercase 'a'—same logic applies to#\e,#\i, etc.(or ...): Combines all equality checks—if any character matches a lowercase vowel, the condition is true.(:= acc (1+ acc))::=is likely a custom macro (not standard Common Lisp) that acts likesetqorsetf—it assigns a new value toacc.(1+ acc)incrementsaccby 1. We need this line to update our count every time we find a vowel—without it,accwould stay at 0 forever, and the function would always return 0!
Quick Summary of the Flow
- Initialize
i=0(starting index),acc=0(vowel counter), andlen(string length). - For each iteration:
- Check if the character at
iis a lowercase vowel. - If yes, increment
accby 1. - Increment
iby 1.
- Check if the character at
- When
ireaches the string length, returnaccas the final count.
内容的提问来源于stack exchange,提问作者snk

