【发布时间】:2017-10-04 09:24:05
【问题描述】:
【问题讨论】:
-
没有一个功能可以做到这一点,如果那是你所要求的。你有没有尝试过这个?
标签: string sorting sas alphabetical
【问题讨论】:
标签: string sorting sas alphabetical
Joe 是对的 - 没有内置函数可以做到这一点。我可以看到这里有两个选项:
call sortc 对数组进行排序。您可以使用 call pokelong 轻松完成此操作,前提是您首先定义了一个足够长的数组。= 符号左侧的substr 来更改单个字符而不重写整个字符串。这是一个示例,说明您可以如何执行 #1。 #2 会做更多的工作。
data _null_;
myword = 'apple';
array letters[5] $1;
call pokelong(myword,addrlong(letters1),5); /*Limit # of chars to copy to the length of array*/
call sortc(of letters[*]);
myword = cat(of letters[*]);
putlog _all_;
run;
注意对于此处使用的长度为 5 的数组,请确保在使用 call pokelong 时仅将字符串的前 5 个字符写入数组开头的内存,以避免溢出数组末尾 - 否则您可以在处理较长的 myword 值时覆盖内存的其他任意部分。这可能会导致不良副作用,例如应用程序/系统崩溃。此外,这种填充数组的技术在 SAS University Edition 中不起作用 - 如果您使用它,则需要使用 do-loop。
我对此做了一个小测试 - 使用几年前 PC 的单个 CPU 对 2m 个长度为 100 的随机单词进行排序,这些单词由从整个 ASCII 可打印范围中选择的字符组成,大约需要 15 秒 - 时间略短用于创建测试数据集。
data have;
length myword $100;
do i = 1 to 2000000;
do j = 1 to 100;
substr(myword,j,1) = byte(32 + int(ranuni(1) * (126 - 32)));
end;
output;
end;
drop i j;
run;
data want;
set have;
array letters[100] $1;
call pokelong(myword,addrlong(letters1),100); /*Limit # of chars to copy to the length of array*/
call sortc(of letters[*]);
myword = cat(of letters[*]);
drop letters:;
run;
【讨论】:
data have; length myword $100; call streaminit(7); do i = 1 to 2000000; do j = 1 to 100; if rand('Uniform') < .05 and j > 5 then leave; substr(myword,j,1) = byte(32 + int(rand('Uniform') * (126 - 32))); end; output; call missing(myword); end; drop i j; run;