APL - Как найти самое длинное слово в векторе строки?

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

⍴ 'string' ⍝ returns 6

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

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

lst ← 'this is a string'

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

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

"Самое длинное слово" может быть 2 или 3...

RosLuP 28.06.2019 08:59
Введение в одну из самых важных концепций в React - функциональное программирование
Введение в одну из самых важных концепций в React - функциональное программирование
React разработан с использованием концепции функционального программирования, поэтому понимание функционального программирования важно для изучения...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
2
1
232
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

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

Спасибо - не подумал об использовании логического метода, который вы описали. Элегантный!

awyr_agored 04.04.2019 13:54

Да, логические значения так полезны в APL — их невозможно переоценить!

MBaas 04.04.2019 13:57

Или просто ≢¨(' '≠lst)⊆lst

Paul Mansour 04.04.2019 14:58

Да! Но это "продвинутый" ;-)

MBaas 04.04.2019 15:21

Хорошо. Только что проверил, как работает пример @Paul Mansour; (i) создать вложенный список отдельных слов; (ii) разделить предложение на слова, используя двоичный вывод (' '≠lst), затем применить функцию подсчета к каждому слову. Спасибо! Это тоже работает: ⍴ ¨(' '≠lst)⊆lst

awyr_agored 04.04.2019 16:15

Конечно. Важно отметить, что tally всегда возвращает простой скаляр, тогда как shape (rho) возвращает вектор. Таким образом, tally, примененный к каждому, возвращает простой вектор, а shape, примененный к каждому, возвращает вложенный вектор.

Paul Mansour 04.04.2019 16:18

@Paul Mansour А, хорошо! Я бы получил ошибку домена, если бы попытался использовать векторный вывод как скаляр.

awyr_agored 04.04.2019 16:19
{¯1+⍵-0,¯1↓⍵}⍸ может быть просто ¯1-2-/⍸
Adám 04.04.2019 18:22

В то время как MBaas уже подробно ответил, я подумал, что было бы интересно узнать идиоматическое 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

спасибо, что нашли время объяснить. АПЛ это круто! !תודה רבה

awyr_agored 05.04.2019 02:23

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

Другие вопросы по теме