SAS - 查找目录中所有数据集的Palindromes

时间:2018-03-12 14:48:18

标签: macros sas palindrome

任务:

我需要识别目录中的所有回文。我使用proc内容和proc排序来识别目录中的数据集,如下所示:

proc contents data = dPath._all_ out = dFiles (keep = memname);
run; 

proc sort data = dFiles nodupkey; by memname;run; 

我想识别此目录中的回文。

问题:

我计划使用宏,因为我需要对目录中的所有数据集执行此操作。因此,不是用户输入字符串来检查是否存在回文,我需要动态完成,即识别数据集中的任何回文。

更新

data_set output full row-WANT SPECIFIC ELEMENT 正如您在上面的图片中看到的那样,我能够成功标记回文以区分大小写和不区分大小写的情况。我想将一个回文的特定元素输出到一个单独的数据集。目前,我只能输出整个行中的回文。

代码:

data palindrome_set (drop = i) palindrome_case_sensitive palindrome_case_insensitive;
            set reverse_rows;
                array palindrome[*] _all_ ;
                do i = 1 to dim(palindrome);
                    palindrome_cs = (trim(palindrome[i]) eq reverse(trim(palindrome[i])));
/*                      if palindrome_cs = 1 then output palindrome[i];                                         WANT TO OUTPUT SPECIFIC ELEMENT, NOT ENTIRE ROW*/
                    palindrome_cis = (lowcase(trim(palindrome[i])) eq reverse(lowcase(trim(palindrome[i]))));
                end;
                output palindrome_set;
                if palindrome_cs = 1 then output palindrome_case_sensitive;         *WANT TO OUTPUT SPECIFIC ELEMENT, NOT ENTIRE ROW;
                if palindrome_cis = 1 then output palindrome_case_insensitive;      *WANT TO OUTPUT SPECIFIC ELEMENT, NOT ENTIRE ROW;
            run;

2 个答案:

答案 0 :(得分:1)

如果memtype =" DATA"那么代码中的Memname将只保存表名。 使用上面的代码检查表名中的回文;尝试:

%macro palindrome (parameter = ); 
%let string = %sysfunc(reverse(%sysfunc(compress("&parameter ",,sp);
%let reverse = %sysfunc(compress(["&parameter ");
%if %upcase(&string.) = %upcase(&reverse.)  %then %do;
ods output = "/palindrome"
%end;

data work.palindromes;
set work.dfiles;
%macro palindrome (parameter = Memname);
run;

答案 1 :(得分:0)

不确定为什么你的图像也显示了变量名称的反转。

可以使用数据步骤函数VNAME()检索与数组引用对应的基础变量名称。此外,可以使用数据步骤函数VVALUE获得变量的格式化值。这两个函数都有动态版本 - VNAMEXVVALUEX。基于阵列的解决方案不需要使用函数的X版本。

通过数组处理所有变量有点棘手,因为您需要额外的变量来执行处理,并且您不希望那些测试用于回文。在此示例中,工作变量名称使用以_pal开头的约定,以避免变量名称与正在处理的数据集冲突。该示例处理单个数据集,但显而易见的是如何对代码进行宏观化并使其适用于传递的数据集名称。

data want(keep=_palds_ _palrow_ _palvar_ _palval_);
  set sashelp.class;

  array _pals_ _character_;  * array elements are those character variables in the pdv at this point in the data step;
  array _palx_ _numeric_;    * array elements are those numeric variables in the pdv at this point in the data step;

  attrib
    _palds_ length  = $42
    _palrow_ length = 8
    _palvar_ length = $32
    _palval_ length = $500
  ;

  * check raw character value;
  do _palindex_ = 1 to dim(_pals_);
    if length (_pals_(_palindex_)) > lengthm(_palval_) then do;
      _palvar_ = vname (_pals_(_palindex_));
      put "NOTE: sashelp.class " _n_= _palVar_ " had a value that is longer than _palval_ container";
      continue;
    end;

    if _pals_(_palindex_) = reverse(trim(_pals_(_palindex_))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_pals_(_palindex_));
      _palval_ = _pals_(_palindex_);
    end;
  end;

  * check formatted numeric value;
  do _palindex_ = 1 to dim(_palx_);
    if left(vvalue(_palx_(_palindex_))) = reverse(trim(vvalue(_palx_(_palindex_)))) then do;
      _palds_ = "sashelp.class";
      _palrow_ = _n_;
      _palvar_ = vname (_palx_(_palindex_));
      _palval_ = _palx_(_palindex_);
    end;
  end;
run;

想要明确避免名称冲突的宏必须对要处理的数据集执行一些注视,以生成不会发生冲突的工作变量名。

如果libref连接到远程主机,则处理libref的所有成员可能会非常占用大量资源 - 因此强大的解决方案可能需要跳过这些成员。

其他一些方法:

  • 使用CALL VNEXT例程迭代pdv变量
  • 使用字典表或proc内容输出作为在不依赖数组的数据步骤中生成变量测试墙的基础。