2016-07-12 3 views
1

Я переношу с Java на Scala, и я пытаюсь придумать слияние процедур для алгоритма mergesort. Мое решение:Слияние для mergesort в 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) 
    } 

, кажется, работает, но мне кажется, что она написана в довольно «императивного» стиле (несмотря на то я не использовал рекурсию и не изменяемые переменные для массивов, за исключением, для которых побочный эффект предназначен). Я хочу что-то вроде этого:

/* 
* 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(<???>) 

Но я не могу найти подходящее решение такого рода. Не могли бы вы мне помочь?

+0

Может быть, ваша проблема принадлежит на http://codereview.stackexchange.com/ .. – meucaa

+1

@meucaa Потенциально, но в настоящее время не написано. Вопрос обзора кода имеет форму «Вот код, который делает X, как бы это было сделано лучше», а не «Вот код, который делает X, как я могу сделать это вместо Y». Если бы OP сбросил вторую часть своего вопроса, это было бы хорошо подходит для CR. – Kaz

+0

@ Zak acturally Я спрашиваю, как это можно сделать лучше, я не хочу, чтобы код ничего не делал вместо слияния. –

ответ

2

Рассмотрим это:

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

Спасибо, это определенно более элегантное решение, чем мое. Вероятно, мне нужно больше читать на итераторах в scala. –