рекурсивная функция в sas для чисел Фибоначчи - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь определить рекурсивную функцию в SAS следующим образом:

%macro f(n);
%if &n<=1 %then %put f(&n)=&n;
%else %put f(&n)=%eval(f(%eval(&n-1))+f(%eval(&n-2)));
%mend;

, но когда i>=2 не работает.

Как мне решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Рекурсивный макрос очень нетипичен.Вы получите гораздо лучший опыт рекурсивного программирования, используя Proc DS2 и реализуя в нем методы.

В любом случае, вы должны понимать, что макрос не является нормальным функциональным языком программирования;это генератор исходного кода с побочными эффектами.Ваш макрос может не излучать какой-либо исходный код и быть запрограммирован исключительно для побочных эффектов, или он может быть записан для генерации исходного кода в соответствии с шаблоном и не иметь других побочных эффектов.

%macro fib(n);

  %if &n < 0 %then %abort cancel;

  %if &n = 0 %then 
    0 /* emit source code 0. The %if is a recursion sentinel */
  ;
  %else 
  %if &n = 1 %then 
    1 /* emit source code 1. The %if is a recursion sentinel */
  ;
  %else %do;
    /* emit source code that is side effect of eval summing recursive invocation */
    %eval (
      %fib(%eval(&n-1)) + %fib(%eval(&n-2))
    )
  %end;

%mend;

%put %fib(0);
%put %fib(1);
%put %fib(2);
%put %fib(3);
%put %fib(4);
%put %fib(5);
%put %fib(6);

Полученный чистый результат равениз макро объекта (подсистема).

% fib (6) генерация кода будет

%put
    %eval (    
      %eval ( /* 5 */
        %eval ( /* 4 */
          %eval ( /* 3 */
            %eval ( /* 2 */
              1 /* 1 */
              +
              0 /* 1 */
            )
            +
            %eval ( /* 1 */
              1
            )
          )
          +
          %eval ( /* 2 */
            1 /* 1 */
            +
            0 /* 1 */
          )
        )
        +
        %eval ( /* 3 */
          %eval ( /* 2 */
            1 /* 1 */
            +
            0 /* 1 */
          )
          +
          %eval ( /* 1 */
            1
          )
        )
      )
      +
      %eval ( /* 4 */
        %eval ( /* 3 */
          %eval ( /* 2 */
            1 /* 1 */
            +
            0 /* 1 */
          )
          +
          %eval ( /* 1 */
            1
          )
        )
        +
        %eval ( /* 2 */
          1 /* 1 */
          +
          0 /* 1 */
        )
      )
    )
;
0 голосов
/ 29 января 2019
%macro f(n);
%if &n<=2 %then 1;
%else  %eval(%f(%eval(&n-1))+%f(%eval(&n-2)));
%mend;
...