2017-06-09 33 views
1

我正在Kotlin中實現Quicksort算法。爲此,我創建了一個界面,其中包含一個類型參數和一個函數,。爲了排序,我需要交換操作。我想知道這個交換功能的最佳位置是什麼。我的想法:Kotlin:Sorting |交換操作的位置

1)不幸的是,在Kotlin中無法保護接口功能。因此,每個班級都可以在其實施中看到交換,這並不太好(儘管這也不算太差,我同意)。

2)把它放在QuickSort實現中更糟,因爲可能有多個需要交換功能的ISort接口的實現。

3)我的下一個想法是創建一個單例對象,但Kotlin允許帶有類型參數的對象。

這裏的接口定義:

interface ISort<T> { 
    fun sort(toSort: MutableList<T>): MutableList<T> 
    // 1) Putting swap here has a too high visibility 
} 

這裏是快速排序類的骨架:

class QuickSort<T> : ISort<T> { 
    override fun sort(toSort: MutableList<T>): MutableList<T> { 
    doQuickSort(toSort) // Internally uses swap 
    return toSort 
    } 
    // 2) Putting swap here might lead to code duplication of swap 
} 

所以,從軟件工程的角度來看這將是最好的地方/位置交換操作。

+0

也許如果你包含一些代碼片段,它會變得更清晰一些。 – nhaarman

+0

我不明白你爲什麼需要交換功能。是'val temp = a; a = b; b =溫度不夠? – Naetmul

+0

我更新了我的問題並添加了一些代碼。 @Naetmul:我知道如何實施互換,但我知道它的最佳位置在哪裏。 – Patrick

回答

1

頂級功能

在文件sort.kt左右,

package abc.def.sort 


fun <T> quicksort(list: MutableList<T>): MutableList<T> { 
    ... 
} 

// invisible in other files, but visibie in "sort.kt" 
private fun <T> swap(...) { 
    ... 
} 

要在其他類型的使用swap功能,您將需要在同一文件中定義其他類型的功能。 (或多次複製swap功能。)

這是推薦用於非常簡單的功能。

對象作爲命名空間

這類似於上面的方法,但更OOP-ISH比前一個。

object QuickSort { 
    fun <T> sort(list: MutableList<T>): MutableList<T> { 
     ... 
    } 

    private fun <T> swap(...) { 
     ... 
    } 
} 

object Sorts { 
    fun <T> quicksort(list: MutableList<T>): MutableList<T> { 
     ... 
    } 

    // add other sort methods... 

    private fun <T> swap(...) { 
     ... 
    } 
} 

然而,這不是在科特林(Best practices for top-level declarations)推薦的。

組合抽象類和對象

swap功能的可再用於其它種類的這種方式。

abstract class Sort { 
    abstract fun <T> sort(list: MutableList<T>): MutableList<T> 

    protected fun <T> swap(...) { 
     ... 
    } 
} 

object QuickSort : Sort() { 
    override fun <T> sort(list: MutableList<T>): MutableList<T> { 
     ... 
    } 
} 

我認爲[製作類型參數T是類類型的參數,而不是一個函數類型參數]會使問題不必要的更加複雜,因爲你將不得不在每次使用不同類型的時間,創建一個類實例T

+0

我怎麼尷尬沒有想到使用抽象類...非常感謝你 – Patrick