簡體   English   中英

如何在功能化的分而治之Java算法中實現功能“分度”?

[英]How can I implement the function “divide” in a functional Divide-And-Conquer Java algorithm?

我正在嘗試實現Quicksort算法的功能版本。 我的教授要求我保留此簽名:

public static <T, R> List<T> myQuickSort(Function<List<T>, Boolean> trivial, 
        Function<List<T>, T> solve, Function<List<T>, R> divide, 
        Function<T, List<R>> combine, List<T> input)

我創建了一個名為Pair的輔助類,它像這樣:

public class Pair {

List<Integer> first; 
List<Integer> second; 

Pair(List<Integer> f, List<Integer> s) {
    first = f; 
    second = s; 
}
public static Pair div(List<Integer> input) {
    int pivot = (int) input.get(0); 
    List<Integer> a = new ArrayList<Integer>();
    List<Integer> b = new ArrayList<Integer>();
    for(int i=1; i<input.size(); i++) {
        if(input.get(i) < pivot) {
            a.add(input.get(i)); 
        } else {
            b.add(input.get(i)); 
        }
    }
    return new Pair(a, b); 
}

我快完成了,但是我無法弄清楚如何在輸入數組的單個分區上遞歸地工作。 我試圖這樣做:

if(trivial.apply(input)) {
        solve.apply(input); 
    } else {
        output = myQuickSort(trivial, solve, divide, combine, 
                (List<T>) divide.apply(input).first); 
        output.add(input.get(0)); 
        output.addAll(myQuickSort(trivial, solve, divide, combine, 
                (List<T>) divide.apply(input).second)); 
        return output; 
    }
    return output;

但是我現在陷入困境。 誰能告訴我哪里錯了,和/或如何更好地實施我的解決方案? 這也是主要的,如果可以幫助的話:

Function<List<Integer>, Boolean> trivial = (a) -> a.size()==1; 
    Function<List<Integer>, Pair> divide = (a) -> Pair.div(input); 
    Function<Pair, List<Integer>> combine = 
            (a) -> Stream.concat(a.first.stream(), a.second.stream()).
            collect(Collectors.toList());
    Function<List<Integer>, Integer> solve = (a) -> a.get(0); 
    ArrayList<Integer> output = myQuickSort(trivial, solve, divide, combine, input);

提出很多問題。 因此,我所能做的就是解決問題。

  1. 我假設在您的myQuickSort簽名中,組合類型已將R和T交換了。 如果我是對的,則如下文所述,我發現這個簽名很奇怪。

  2. 您代碼中的“ solve.apply()”行對返回值不起作用。 由於您不使用對該函數的調用返回,因此我無法確定“解決”的目的是什么。 也許你可以澄清一下。 結果,您的最后一個“返回輸出”將不返回任何內容。 在下面的討論中,我將忽略“解決”。

  3. 您主要實現的“組合”不必要地使用了流。 List.addAll()可以解決問題。

  4. 您無需在實現中使用Combine函數。

我的問題與您的教授給您的簽名有關。 在我看來,R是代表被分成兩個列表的對象。 R將包括第一個和第二個列表,以及您稱為的“樞軸”。 然后,合並使用R,並將這三個部分合並到一個列表中。 由於R,除法和合並的實現是由myQuickSort的調用者完成的,因此它們將處理正在排序的對象(實現中為Integers)的比較,因此myQuickSort不必知道所對象的類型。排序。

如果我是對的,那么在我看來,R的實現(稱為對)應該存儲數據透視表。 然后,您的Combine實施將首先結合,樞軸和再結合。 除法或組合將調用myQuickSort:無關緊要。 您對此有分歧,這很好。

那么myQuickSort將會是:

if (trivial(input))
    return input;    // Remember I am ignoring solve()
else {
    R r = divide.apply(input);
    return combine.apply(r);
}

因此,除法或合並的實現(在您的情況下為除法)將通過為分割列表的兩半調用myQuickSort來提供遞歸。

如果我對上述內容是正確的,這是一個奇怪的簽名。 提供的功能必須具有QuickSort實現的知識。 如果將R定義為具有myQuickSort可以操縱分割數組的方法,則情況並非如此。 這意味着,與其說在靜態方法簽名中不簡單使用R,還不如說是使用“ R extended DivObject”,其中DivObject是定義myQuickSort可以調用的方法的接口(或類)。 我會讓DivObject有一個getFirst()方法和一個getSecond()方法,它們返回相應的列表,以便myQuickSort可以在這兩個列表上調用自身。 它還需要像setFirst()和setSecond()這樣的方法將排序后的列表放回R中,以便合並可以合並它們(因為合並僅將R作為參數)。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM