由于我是J的初学者,我决定使用这种语言解决一个简单的任务,特别是实现bubblesort算法。我知道在函数式语言中解决这类问题不是惯用的,因为它在C等命令式语言中使用数组元素转换自然解决,而不是在声明性语言中构造修改后的列表。然而,这是我写的代码:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
这是声明的结构:
┌────────────────────────────────────────────────────────────────────────────┬──┬─┐
│┌───────────────────────────────────────────────────────────────┬──┬───────┐│^:│#│
││┌───────────────────┬─┬───────────────────────────────────────┐│^:│┌─┬─┬─┐││ │ │
│││┌──────┬─┬────────┐│,│┌──┬─┬────────────────────────────────┐││ ││1│<│#│││ │ │
││││┌──┬─┐│@│┌─┬─┬──┐││ ││$:│@│┌───────────────────┬─┬────────┐│││ │└─┴─┴─┘││ │ │
│││││<.│/││ ││2│&│{.│││ ││ │ ││┌──────┬─┬────────┐│,│┌─┬─┬──┐││││ │ ││ │ │
││││└──┴─┘│ │└─┴─┴──┘││ ││ │ │││┌──┬─┐│@│┌─┬─┬──┐││ ││2│&│}.│││││ │ ││ │ │
│││└──────┴─┴────────┘│ ││ │ ││││>.│/││ ││2│&│{.│││ │└─┴─┴──┘││││ │ ││ │ │
│││ │ ││ │ │││└──┴─┘│ │└─┴─┴──┘││ │ ││││ │ ││ │ │
│││ │ ││ │ ││└──────┴─┴────────┘│ │ ││││ │ ││ │ │
│││ │ ││ │ │└───────────────────┴─┴────────┘│││ │ ││ │ │
│││ │ │└──┴─┴────────────────────────────────┘││ │ ││ │ │
││└───────────────────┴─┴───────────────────────────────────────┘│ │ ││ │ │
│└───────────────────────────────────────────────────────────────┴──┴───────┘│ │ │
└────────────────────────────────────────────────────────────────────────────┴──┴─┘
让我们将它应用于数组:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: # 5 3 8 7 2
2 3 5 7 8
令我困惑的是$:
引用最外面括号内的陈述。 Help说:
$:
表示最长的动词 包含它。
The other book(约300 KiB)说:
3+4
7
5*20
100
+和*的符号用于加上和 调用上述短语中的次 动词和代表功能。你可以 在J短语中有多个动词, 在这种情况下它的构造就像 用阅读简单英语的句子 从左到右,就是这样
4+6%2
表示4
添加到后面的内容中,即6
除以2
。
让我们重写我的代码段,省略最外面的()
s:
((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#) ^: # 5 3 8 7 2
2 3 5 7 8
Reuslts是一样的。我无法解释自己为什么会这样做,为什么只有((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
被视为$:
的最长动词,而不是整个表达式((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#) ^: #
而不只是(<./@(2&{.)), $:@((>./@(2&{.)),2&}.)
,因为如果((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
是一个动词,它应该在与#
结合后形成另一个动词,i。即有人可能将整个句子(第一个片段)视为动词。对于一个连词限制的动词长度,可能存在一些限制。
查看以下代码(from here):
factorial =: (* factorial@<:) ^: (1&<)
factorial 4
24
表达式中的 factorial
指整个函数,即。即(* factorial@<:) ^: (1&<)
。
按照这个例子,我使用的是函数名而不是$:
:
bubblesort =: (((<./@(2&{.)), bubblesort@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
bubblesort 5 3 8 7 2
2 3 5 7 8
我希望bubblesort
能够引用整个函数,但由于结果是正确的,因此对我来说似乎不正确。
如果你有其他实现,我也希望看到其他实现,甚至是稍微重构的。
感谢。
答案 0 :(得分:1)
我在调查它。在此期间,您是否正在实施bubblesort,因为您需要特别使用bubblesort,或者因为您只是需要一种排序(即您可以使用/:~
代替)?
编辑:您是否尝试在3 1 2 9 2 9 86 5 9 6 9 6 45
等数据集上运行冒泡排序?当我在我的机器上尝试它时系统挂起,但如果你用_。
答案 1 :(得分:1)
根据this reference(175 KiB)结合是:
需要两个的词性 参数通常导致a 动词。例如,
*:^:3
是一个 迭代平方三的函数 时间(^:
是连词)。
由于^:
属于上述类别,将其应用于参数会产生更长的动词:
((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
因为$:
表示包含它的最长动词,所以它指的是上面刚写的代码。
同样,下一个^:
会从((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
和#
创建一个新的较长动词:
(((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)) ^: #
反过来由$:
引用,因为它比前一个更长。
由于这是不受欢迎的行为,可能唯一的解决方案是拆分整个动词,以便$:
引用((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
,尽管它不是oneliner:
bubbleiter =: ((<./@(2&{.)), $:@((>./@(2&{.)),2&}.)) ^: (1<#)
bubblesort =: bubbleiter ^: #
bubblesort 3 1 2 9 2 9 86 5 9 6 9 6 45
1 2 2 3 5 6 6 9 9 9 9 45 86
This article对$:
:
解释
$:
(自我引用) 是以及它是如何使用的结果 一个相当不幸的起点 对于一些全新的 这是一种先进的语言 功能和非典型的方式 事情通常在J. John完成 提到罗杰评论道 如果他,他不会包括这个 正在设计这种语言。
再一次,总结一下:
^:
是一个连词,并从其参数中创建一个新的动词; $:
表示包含它的最长动词。在他的回答中,感谢飞出estanford数据集3 1 2 9 2 9 86 5 9 6 9 6 45
。
答案 2 :(得分:0)
这是在J中实现冒泡排序的另一种方法:http://rosettacode.org/wiki/Sorting_algorithms/Bubble_sort#J