Common lisp Lisp:创建随机奇数

Common lisp Lisp:创建随机奇数,common-lisp,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))) 应该会产生这样的结果: ((A . 37) (B . 283) (C . 232) (D . 251) (E .

我有这个:

(let ((num 1))
  (mapcar (lambda (x)
            (cons x (if (evenp (setf num (random 299)))
                        (1+ num)
                        (num))))
          '(a b c d e f)))
应该会产生这样的结果:

 ((A . 37) (B . 283) (C . 232) (D . 251) (E . 273) (F . 170) 
只有奇数。是的,看起来很邋遢。对于
随机状态
是否有帮助?还是保留初始
随机
计算的“隐藏系统变量”?下面是我尝试过的一个全局函数:

(defun random-odd ()
  (let ((num 0))
    (if (evenp (setf num (random 299)))
        (1+ num)
      (num))))

也不起作用。我这里缺少什么?

除了样式和在中使用
num
之外,您的
random odd
几乎没有问题 函数位置(记住,):

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

这是因为返回0到298之间的数字,概率为1/299。因此,
random odd
将返回17,概率为2/299(如果
random
返回17或16),但它将返回299,概率为1/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)))
完全等效的方法是

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

您的
random-odd
几乎没有问题,除了样式和在中使用
num
之外 函数位置(记住,):

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

这是因为返回0到298之间的数字,概率为1/299。因此,
random odd
将返回17,概率为2/299(如果
random
返回17或16),但它将返回299,概率为1/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)))
完全等效的方法是

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


我想你想要这样的东西:f()=>rand()*2+1为什么你的函数中需要SETF?应该做什么?请复制并粘贴完整的错误消息,而不是说“不工作”。是的,
rand()*2+1
是数学家的手笔。对,
(num)
完全是我的哑巴。下次还会有更多的错误。我想你想要这样的东西:f()=>rand()*2+1为什么你的函数中需要SETF?应该怎么做?请复制并粘贴完整的错误消息,而不是说“不工作”。是的,
rand()*2+1
是数学家的手笔。对,
(num)
完全是我的哑巴。下一次的错误也会更加详细。使用(1+(*2(随机150)),不是更有意义吗?虽然我的统计知识有点薄弱。澄清一下,似乎×2+1避免了大量不必要的计算,同时又不牺牲太多(如果有的话)清晰性,但我不确定它是否会以某种方式微妙地显示结果。结果是,除非有人拥有比我预期更好的优化器,我认为比较和分支或增量会增加一些开销。与缺点相比可能微不足道,但是/耸耸肩。@brfennpock但您必须计算半极限而不是实际极限;-)当然,但是每个优化器都可以做一个÷2=Ash-1,这是在循环之外的。我知道,我处理的利润比大多数人关心的都要少,但是/耸耸肩…我想定义编译器宏总是存在的。使用(1+(*2(random 150))不是更有意义吗?虽然我的统计知识有点薄弱。澄清一下,似乎×2+1避免了大量不必要的计算,同时又不牺牲太多(如果有的话)清晰性,但我不确定它是否会以某种方式微妙地显示结果。结果是,除非有人拥有比我预期更好的优化器,我认为比较和分支或增量会增加一些开销。与缺点相比可能微不足道,但是/耸耸肩。@brfennpock但您必须计算半极限而不是实际极限;-)当然,但是每个优化器都可以做一个÷2=Ash-1,这是在循环之外的。我知道,我的利润比大多数人都要少,但我想,定义编译器宏总是存在的。谢谢karsten,这就是我所做的,将它嵌入到
flet
中。忘了你可以把
let
放在
mapcar
里。谢谢卡斯滕,这就是我所做的,把它嵌入
flet
。忘了你可以把
let
放在
mapcar
里。