按字母顺序排列字符串中的字母 - SAS
我想按字母顺序排列字符串中的字母。按字母顺序排列字符串中的字母 - SAS
E.g.
'apple' = 'aelpp'
我已经看到,有些类似的唯一功能是SORTC,但我想,以避免分裂每个字成书,如果可能的数组。
乔的权利 - 没有这样做的内置函数。您可以在这里看到两个选项:
- 将字符串拆分为数组并使用
call sortc
对数组进行排序。您可以使用call pokelong
非常轻松地完成此操作,前提是您首先定义了足够长度的数组。 - 实施您选择的sorting algorithm。如果您选择沿着这条路线走,我建议在
=
符号的左侧使用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;
N.B.对于这里使用的长度为5的数组,请确保仅在使用call pokelong
时才将字符串的前5个字符写入数组的起始处的内存中,以避免溢出超过数组的末尾 - 否则可以覆盖一些当处理更长的值myword
时,其他任意部分的内存。这可能导致不希望的副作用,例如应用程序/系统崩溃。此外,用于填充数组的这种技术在SAS大学版中不起作用 - 如果您正在使用该技术,则需要使用do循环。
我对此进行了一些测试 - 排序长度为100的2m随机单词,包含从整个ASCII可打印范围中选择的字符,使用几年前PC的单个CPU花费大约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;
你有什么想法#1会是多么昂贵?我有大约200万条记录。最终,我将使用第二个列表和[SPEDIS](http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000245949.htm)搜索最近的比赛。我知道这可能是做模糊匹配的一种奇怪的方式,但有一些突出的情况使我相信这是最好的方法。 –
@JamesSteele增加了一项测试 - 限制因素(与SAS通常一样)似乎是磁盘I/O。 – user667489
这是一个很好的解决方案,除了一件事:空白字符串中的空格。我会做两个更改:一个用于生成例程,一个用于WANT datastep。 – Joe
有没有一个功能,只是这样做,如果这是你问。你有没有尝试过呢? – Joe