Common LISP中(81 2 2)多维数组洗牌报错:LOOP宏中PATTERNS为未知关键字
LISP数组打乱代码报错修复方案
核心错误原因
- 调用方式错误:你调用函数时写了
(shuffle (list patterns)),相当于把目标数组包裹成了列表传入函数,函数内部array-dimension方法无法处理列表类型的输入。 - LOOP宏语法错误:你在
do子句的执行块结束后直接写了patterns作为返回值,LOOP宏的语法要求所有子句必须以可识别的关键字开头,无关键字的patterns会被识别为未知关键字,这就是你收到报错的直接原因。 - 执行块包裹错误:
do关键字后如果需要执行多个表达式,不能直接用普通括号包裹,必须用progn关键字包裹,否则Lisp会将括号内第一个表达式的返回值作为函数尝试调用,引发二次错误。 - 变量未声明:直接用
setq给x、y赋值会意外创建全局变量,存在变量污染风险。 - 硬编码不灵活:随机数范围硬编码为81,修改数组维度后代码会失效。
修复后的代码
函数实现(采用标准Fisher-Yates洗牌算法保证公平性)
(defun shuffle (patterns) (loop with arr-len = (array-dimension patterns 0) for i from (1- arr-len) downto 1 for j = (random (1+ i)) do (rotatef (aref patterns i 0 0) (aref patterns j 0 0) (aref patterns i 0 1) (aref patterns j 0 1) (aref patterns i 1 0) (aref patterns j 1 0) (aref patterns i 1 1) (aref patterns j 1 1)) finally (return patterns)))
正确调用方式
直接传入数组即可,不需要包裹list:
(shuffle patterns)
内容的提问来源于stack exchange,提问作者Hailey White
相关产品推荐
相关产品推荐

