J:冒泡排序默认实现中的自我引用

时间:2010-05-08 07:42:42

标签: algorithm functional-programming bubble-sort j tacit-programming

由于我是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能够引用整个函数,但由于结果是正确的,因此对我来说似乎不正确。

如果你有其他实现,我也希望看到其他实现,甚至是稍微重构的。

感谢。

3 个答案:

答案 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