APL - 如何找到字符串向量中最长的单词?

APL - How can I find the longest word in a string vector?

我想在字符串向量中找到最长的单词。使用 APL 我知道形状函数将 return 字符串的长度,例如

⍴ 'string' ⍝ returns 6

reduce 函数允许我沿向量映射二元函数,但由于形状是一元的,所以这将不起作用。在这种情况下如何映射形状函数?例如:

如果向量定义为:

lst ← 'this is a string'

我想这样做:

⍴'this' ⍴'is' ⍴'a' ⍴'string'

"typical" 方法是将其视为分段(或:分隔)字符串并在其前面加上分隔符 (空白)并将其传递给用于进一步分析的 dfn:

{}' ',lst

然后 fn 查找分隔符并使用它来构建单词向量:

      {(⍵=' ')⊂⍵}' ',lst
┌─────┬───┬──┬───────┐
│ this│ is│ a│ string│
└─────┴───┴──┴───────┘

让我们去掉空格:

      {1↓¨(⍵=' ')⊂⍵}' ',lst
┌────┬──┬─┬──────┐
│this│is│a│string│
└────┴──┴─┴──────┘

然后你"just"需要计算每个向量的长度:

{1↓¨(⍵=' ')⊂⍵}' ',lst

这是对您的请求的直接执行。但是,如果您对子字符串本身不感兴趣,而只对 "non-blank segments" 的长度感兴趣,则更 "APLy" 的解决方案可能是使用布尔值(通常最有效):

      lst=' '
0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0

所以这些是分隔符的位置 - 它们出现在哪里?

      ⍸lst=' '
5 8 10

但我们也需要尾随空白 - 否则我们会错过文本结尾:

      ⍸' '=lst,' '
5 8 10 17

所以这些(minus the positions of the preceeding blank)应该给出段的长度:

      {¯1+⍵-0,¯1↓⍵}⍸' '=lst,' '
4 2 1 6

这仍然有些天真,可以用更高级的方式表达 - 我将其保留为 "exercise for the reader" ;-)

同时 , I thought it might be interesting to learn the idiomatic Dyalog "train" ≠⊆⊢ derived from 。它形成一个二元函数,在出现左参数时拆分右参数:

      Split ← ≠⊆⊢
      ' ' Split 'this is a string'
┌────┬──┬─┬──────┐
│this│is│a│string│
└────┴──┴─┴──────┘

您可以扩展这个函数来完成整个工作:

      SegmentLengths ← ≢¨Split
      ' ' SegmentLengths 'this is a string'
4 2 1 6

甚至可以一次性组合定义:

      SegmentLengths ← ≢¨≠⊆⊢
      ' ' SegmentLengths 'this is a string'
4 2 1 6

如果您习惯了惯用表达式 ≠⊆⊢ 那么它实际上可能比您可以为该函数提供的任何合适的名称都读起来更清晰,因此您不妨直接使用该表达式:

      ' ' (≢¨≠⊆⊢) 'this is a string'
4 2 1 6

关于如何在字符串中找到最长的单词我会使用,在 NARS APL 中函数

f←{v/⍨k=⌈/k←≢¨v←(⍵≠' ')⊂⍵}

使用示例

  f  'this is a string thesam'
string thesam 

说明

{v/⍨k=⌈/k←≢¨v←(⍵≠' ')⊂⍵}
            v←(⍵≠' ')⊂⍵  split the string where are the spaces and assign result to v
        k←≢¨v             to each element of v find the lenght, the result will be a vector
                          that has same lenght of v saved in k
      ⌈/k                 this find max in k
    k=                    and this for each element of k return 0 if it is not max, 1 if it is max
 v/⍨                      this return the element of v that are max