如何使用J排序

时间:2016-03-21 12:17:41

标签: arrays sorting j

我习惯于操作排序,这是多种语言所能提供的。它需要一些比较器和排序。 我想要做的是先按照长度然后按字母顺序对以下单词进行排序。请帮帮我。

除了排序和评分数值之外,我在jsoftware的短语或词典中没有找到任何关于它的内容。

   words=: >;:'CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER'
   ] alpha=: a. {~ (i.26) + a.i.'A'
ABCDEFGHIJKLMNOPQRSTUVWXYZ
   ;/ words/: alpha i. words
┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
│CLIENT  │CLOUD   │FIREWIRE│LAN     │NETWORK │PEER    │SERVER  │USB     │
└────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘

我的第一个疯狂想法是将每个单词移到数组的右边界,例如

 ABC
DEFG
  XY

然后为空白分配极端排名(在 y 排序原语的参数中)。然后将每个单词移回:D。这将非常低效,我看不到另一种J-way。

更新
这是我的问题的 Wolfram语言代码:

StringSplit @ "CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER"
~SortBy~
(Reverse @ ComposeList[{StringLength}, #] &)

如果我想优先考虑较长的字词,我只需将Minus @*追加到StringLength即可。 基本上我的排序顺序是{{5, "CLOUD"}, {3, "USB"}, {7, "NETWORK"}, ...}

我可以使用应用于盒装单词的(,.~ #&.>)在J中创建相同的数组,但是如何使用排序原语呢?也许这是正确的第一步?我仍然不确定,但听起来比我的第一次猜测要好:)

1 个答案:

答案 0 :(得分:1)

根据要求,我已将评论中建议的答案提升为答案正文。

首先,我认为将>应用于单词列表并不是一个好主意,因为这会添加填充,这会破坏有关每个单词长度的信息。所以从

开始
   words=: ;:'CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER'

然后你需要一个函数foo,它将每个单词变成一个值,使用\:/:

按照你想要的顺序排序
   words \: foo words

会做到这一点。或者,根据你认为钩子是漂亮还是丑陋,你可以表达为

   (/: foo) words

我对foo的原始建议使用了#。将每个单词表示为单个数字:

   foo=: (128&#.)@(a.&i.)@>
   foo words
18145864388 1403330 345441182148939 1253582 2870553715410 39730390339053893 2322657797972 168911570

   (/: foo) words
┌───┬───┬────┬─────┬──────┬──────┬───────┬────────┐
│LAN│USB│PEER│CLOUD│CLIENT│SERVER│NETWORK│FIREWIRE│
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘

在评论中,Danylo Dubinin指出,我们可以简单地将单词长度连接到索引向量的前面,并使用它进行排序,而不是对单词进行编码:

   (/: (# , a.&i.)@>) words
┌───┬───┬────┬─────┬──────┬──────┬───────┬────────┐
│LAN│USB│PEER│CLOUD│CLIENT│SERVER│NETWORK│FIREWIRE│
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘
相关问题