APL - Как мне найти самое длинное слово в строковом векторе? - PullRequest
1 голос
/ 04 апреля 2019

Я хочу найти самое длинное слово в строковом векторе. Используя APL, я знаю, что функция shape будет возвращать длину строки, например

⍴ 'string' ⍝ returns 6

Функция приведения позволяет мне отображать диадические функции вдоль вектора, но поскольку форма является монадической, это не сработает. Как я могу отобразить функцию формы в этом случае? Например:

Если вектор определен как:

lst ← 'this is a string'

Я хочу сделать это:

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

Ответы [ 3 ]

2 голосов
/ 04 апреля 2019

Хотя MBaas уже полностью ответил , я подумал, что было бы интересно узнать идиоматический "поезд" Диалога ≠⊆⊢, полученный из комментария Пола Мансура . Он формирует двоичную функцию, которая разбивает свой правый аргумент на вхождения левого аргумента:

      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
2 голосов
/ 04 апреля 2019

«Типичный» подход заключается в том, чтобы рассматривать его как сегментированную (или: разделенную) строку и ставить префикс с разделителем (пробел ) и передавать его в 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

Это все еще несколько наивно и может быть выражено более продвинутым способом - я оставляю это как "упражнение для читателя"; -)

0 голосов
/ 28 июня 2019

Как найти самое длинное слово в строке, которое я использовал бы, в 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
...