2016-07-12 21 views
1

Ich migriere von Java zu Scala und ich versuche, mit der Prozedur Merge für Mergesort-Algorithmus zu kommen. Meine Lösung:Zusammenführen für Mergesort in Scala

def merge(src: Array[Int], dst: Array[Int], from: Int, 
      mid: Int, until: Int): Unit = { 

     /* 
     * Iteration of merge: 
     * i - index of src[from, mid) 
     * j - index of src[mid, until) 
     * k - index of dst[from, until) 
     */ 
     @tailrec 
     def loop(i: Int, j: Int, k: Int): Unit = { 
      if (k >= until) { 
       // end of recursive calls 
      } else if (i >= mid) { 
       dst(k) = src(j) 
       loop(i, j + 1, k + 1) 
      } else if (j >= until) { 
       dst(k) = src(j) 
       loop(i + 1, j, k + 1) 
      } else if (src(i) <= src(j)) { 
       dst(k) = src(i); 
       loop(i + 1, j, k + 1) 
      } else { 
       dst(k) = src(j) 
       loop(i, j + 1, k + 1) 
      } 
     } 
     loop(from, mid, from) 
    } 

scheint, zu arbeiten, aber es scheint mir, dass es in ganz „Imperativ“ Stil geschrieben (trotz i Rekursion und keine änderbaren Variablen verwendet habe mit Ausnahme der Felder, für die die Nebenwirkung ist gewünscht). Ich möchte etwas wie das:

/* 
* this code is not working and at all does the wrong things 
*/ 
for (i <- (from until mid); j <- (mid until until); 
    k <- (from until until) if <???>) yield dst(k) = src(<???>) 

Aber ich kann nicht mit der richtigen Lösung dieser Art kommen. Kannst du mir bitte helfen? diese

+0

Vielleicht ist Ihr Problem gehört auf http://codereview.stackexchange.com/ .. – meucaa

+1

@meucaa Potenziell, aber nicht, wie sie derzeit geschrieben. Code Review-Fragen haben die Form "Hier ist Code, der X tut, wie könnte es besser gemacht worden sein" als "Hier ist Code, der X tut, wie kann ich es stattdessen Y machen". Wenn das OP den zweiten Teil seiner Frage fallen ließ, würde es sich gut für CR eignen. – Kaz

+0

@Zak acturally Ich frage, wie dies besser gemacht werden kann, ich möchte nicht, dass der Code etwas statt Merge tun. –

Antwort

2

Bedenken Sie:

val left = src.slice(from, mid).buffered 
    val right = src.slice(mid, until).buffered 

    (from until until) foreach { k => 
    dst(k) = if(!left.hasNext) right.next 
     else if(!right.hasNext || left.head < right.head) left.next 
     else right.next 
    } 
+0

Danke, das ist definitiv elegantere Lösung als meine. Wahrscheinlich muss ich auf Iteratoren in Scala mehr nachlesen. –