Lisp:创建随机奇数

147*_*7pm 0 common-lisp

我有这个:

(let ((num 1))
  (mapcar (lambda (x)
            (cons x (if (evenp (setf num (random 299)))
                        (1+ num)
                        (num))))
          '(a b c d e f)))
Run Code Online (Sandbox Code Playgroud)

应该产生这样的东西:

 ((A . 37) (B . 283) (C . 232) (D . 251) (E . 273) (F . 170) 
Run Code Online (Sandbox Code Playgroud)

只有奇数.是的,很奇怪的样子.有什么东西random-state可以帮助吗?或者保留初始random计算的"隐藏系统变量" ?这是我尝试过的全局函数:

(defun random-odd ()
  (let ((num 0))
    (if (evenp (setf num (random 299)))
        (1+ num)
      (num))))
Run Code Online (Sandbox Code Playgroud)

也行不通.我在这里错过了什么?

sds*_*sds 5

random-odd除了样式和num在函数位置使用之外你几乎没问题(记住,Lisp括号是有意义的):

(defun random-odd ()
  (let ((num (random 299)))
    (if (evenp num)
        (1+ num)
        num)))
Run Code Online (Sandbox Code Playgroud)

这个函数的一个微妙问题是得到299 的概率是从1到297获得任何其他奇数的概率的一半.

这是因为(random 299)从0到298(包括0和298)的返回数字具有相等的概率1/299.因此random-odd将返回17,概率为2/299(如果random返回17或16),但它将以概率1/299返回299(如果random返回298).

因此我建议

(defun random-odd (even-limit)
  "Return an odd random number from 0 to EVEN-LIMIT, exclusive."
  (assert (evenp even-limit) (even-limit)
          "~S: ~S must be even" 'random-odd 'even-limit)
  (let ((num (random even-limit)))
    (if (evenp num)
        (1+ num)
        num)))
Run Code Online (Sandbox Code Playgroud)

一种完全相同的方法

(defun random-odd (half-limit)
  "Return a random odd number from 1 to half-limit*2-1 inclusive."
  (1+ (ash (random half-limit) 1)))
Run Code Online (Sandbox Code Playgroud)