按字母顺序对字母串中的字母排序 - SAS

时间:2017-05-05 19:42:17

标签: string sorting sas alphabetical

我想按字母顺序对字母中的字母进行排序。

E.g。

System.Net.Mail.SmtpException: The address has an invalid host name: DAAIRMAN23@GMAIL.COM‏. ---> System.ArgumentException: Decoded string is not a valid IDN name.
Parameter name: unicode
   at System.Globalization.IdnMapping.GetAsciiUsingOS(String unicode)
   at System.Globalization.IdnMapping.GetAscii(String unicode, Int32 index, Int32 count)
   at System.Globalization.IdnMapping.GetAscii(String unicode, Int32 index)
   at System.Net.Mail.MailAddress.GetHost(Boolean allowUnicode)
   --- End of inner exception stack trace ---
   at System.Net.Mail.MailAddress.GetHost(Boolean allowUnicode)
   at System.Net.Mail.MailAddress.GetAddress(Boolean allowUnicode)
   at System.Net.Mail.MailAddress.GetSmtpAddress(Boolean allowUnicode)
   at System.Net.Mail.SmtpClient.ValidateUnicodeRequirement(MailMessage message, MailAddressCollection recipients, Boolean allowUnicode)
   **at System.Net.Mail.SmtpClient.Send(MailMessage message)**

我见过的唯一有点相似的函数是SORTC,但我想尽可能避免将每个单词拆分成一个字母数组。

1 个答案:

答案 0 :(得分:2)

乔是对的 - 没有内置功能可以做到这一点。你可以在这里看到两个选项:

  1. 将字符串拆分为数组,并使用call sortc对数组进行排序。您可以使用call pokelong相当轻松地完成此操作,前提是您已首先定义了足够长度的数组。
  2. 实施您选择的sorting algorithm。如果您选择沿着此路线前进,我建议您使用substr符号左侧的=来更改单个字符,而无需重写整个字符串。
  3. 这是一个如何做#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-loop。

    我对此做了一点测试 - 排序长度为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;