具有嵌套循环的C ++程序的Common Lisp代码

时间:2018-03-19 01:52:33

标签: c++ common-lisp code-translation

我是Common Lisp的初学者,但在C ++中却不是这样。 有一个简单的C ++程序,我试图在CL中镜像(参见Pollard's Rho algorithm variant example in C++ )。 C ++程序运行没有错误。一个要求是两个程序的所有输出必须匹配。

C ++版

int gcd(int a, int b) {
    int remainder;
    while (b != 0) {
        remainder = a % b;
        a = b;
        b = remainder;
    }
    return a;
}

int prime () {
    int n = 10403, x_fixed = 2, cycle_size = 2, x = 2, factor = 1;

    while (factor == 1) {
        for (int count=1;count <= cycle_size && factor <= 1;count++) {
            x = (x*x+1)%n;
            factor = gcd(x - x_fixed, n);
        }

        cycle_size *= 2;
        x_fixed = x;
    }
    cout << "\nThe factor is  " << factor;
return 0;
}

Common Lisp版本

这是我想出来的。调试给了我噩梦,但我尝试了很多次并完成整个代码,但我仍然不知道我哪里出错了:(

(defun prime () 
  (setq n 10403) 
  (setq x_fixed 2) 
  (setq cycle_size 2)
  (setq x 2) 
  (setq factor 1)
  (setq count 1) 
  (while_loop))

(defun while_loop () 
  (print
    (cond ((= factor 1) 
           (for_loop)
           (setf cycle_size (* cycle_size 2))
           (setf x_fixed x) 
           (setf count 1)
           (while_loop))

          ((/= factor 1) "The factor is : ")))
  (print factor))

(defun for_loop () 
    (cond ((and (<= count cycle_size) (<= factor 1)) 
           (setf x (rem (* x (+ x 1)) n)) 
           (setf factor (gcd (- x x_fixed) n)))
          ((or (<= count cycle_size) (<= factor 1)) 
           (setf count (+ count 1)) (for_loop))))

备注

  • 我将所有变量和常量命名为与C ++版本相同。
  • 我花了半天的时间来决定是否提出这个问题
  • 如果我的Common Lisp代码看起来有趣或愚蠢,你可以随心所欲地

2 个答案:

答案 0 :(得分:5)

您需要定义局部变量。

C代码的基本翻译看起来与此类似:

(defun my-gcd (a b)
  (let ((remainder 0))
    (loop while (/= b 0) do
          (setf remainder (mod a b)
                a b
                b remainder))
    a))

或使用类型声明:

(defun my-gcd (a b)
  (declare (integer a b))
  (let ((remainder 0))
    (declare (integer remainder))
    (loop while (/= b 0) do
          (setf remainder (mod a b)
                a b
                b remainder))
    a))

Common Lisp中的integer数据类型是无界的 - 与C ++中的int不同。

答案 1 :(得分:3)

你真的需要在Common Lisp上做更多的阅读。它具有C ++的所有基本命令结构,因此不需要经历仅仅转换简单算法的扭曲。请参阅示例Guy Steele's classic, available for free

这是一个更合理和惯用的反码:

(defun prime-factor (n &optional (x 2))
  (let ((x-fixed x)
        (cycle-size 2)
        (factor 1))
    (loop while (= factor 1)
      do (loop for count from 1 to cycle-size
           while (<= factor 1)
           do (setq x (rem (1+ (* x x)) n)
                    factor (gcd (- x x-fixed) n)))
         (setq cycle-size (* 2 cycle-size)
               x-fixed x)))
    factor))

(defun test ()
  (prime-factor 10403))