【问题标题】:APL - How can I find the longest word in a string vector?APL - 如何在字符串向量中找到最长的单词?
【发布时间】:2019-08-26 02:36:41
【问题描述】:

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

⍴ 'string' ⍝ returns 6

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

如果向量定义为:

lst ← 'this is a string'

我想这样做:

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

【问题讨论】:

  • “最长的单词”可以是2或3 ...

标签: functional-programming apl dyalog gnu-apl


【解决方案1】:

关于如何在我将使用的字符串中找到最长的单词,在 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

【讨论】:

    【解决方案2】:

    虽然MBaas has already thoroughly answered,但我认为学习源自Paul Mansour's comment 的惯用Dyalog“火车”≠⊆⊢ 可能会很有趣。它形成了一个二元函数,它在左参数出现时拆分其右参数:

          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
    

    【讨论】:

    • 感谢您花时间解释。 APL 很酷! !תודה רבה
    【解决方案3】:

    “典型”方法是将其视为分段(或:分隔)字符串,并在其前面加上分隔符 (空白)并将其传递给 dfn 以供进一步分析:

    {}' ',lst
    

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

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

    让我们删除空白:

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

    然后你“只”需要计算每个向量的长度:

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

    这是您请求的直接实现。但是,如果您对子字符串本身不感兴趣,而只对“非空白段”的长度感兴趣,则更“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
    

    这仍然有点幼稚,可以用更高级的方式表达——我把它作为“读者练习”;-)

    【讨论】:

    • 谢谢 - 没想到使用你描述的布尔方法。优雅!
    • 是的,布尔值在 APL 中非常有用 - 它们不能被高估!
    • 或者只是≢¨(' '≠lst)⊆lst
    • 是的!但那是“高级”;-)
    • {¯1+⍵-0,¯1↓⍵}⍸ 可以只是¯1-2-/⍸
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多