Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My solution (bound to Int, but should be easily changed to Ordered (a few minutes please): </p> <pre><code>def top (n: Int, li: List [Int]) : List[Int] = { def updateSofar (sofar: List [Int], el: Int) : List [Int] = { // println (el + " - " + sofar) if (el &lt; sofar.head) (el :: sofar.tail).sortWith (_ &gt; _) else sofar } /* better readable: val sofar = li.take (n).sortWith (_ &gt; _) val rest = li.drop (n) (sofar /: rest) (updateSofar (_, _)) */ (li.take (n). sortWith (_ &gt; _) /: li.drop (n)) (updateSofar (_, _)) } </code></pre> <p>usage:</p> <pre><code>val li = List (4, 3, 6, 7, 1, 2, 9, 5) top (2, li) </code></pre> <ul> <li>For above list, take the first 2 (4, 3) as starting TopTen (TopTwo). </li> <li>Sort them, such that the first element is the bigger one (if any).</li> <li>repeatedly iterate through the rest of the list (li.drop(n)), and compare the current element with the maximum of the list of minimums; replace, if neccessary, and resort again. </li> <li>Improvements: <ul> <li>Throw away Int, and use ordered. </li> <li>Throw away (_ > _) and use a user-Ordering to allow BottomTen. (Harder: pick the middle 10 :) )</li> <li>Throw away List, and use Iterable instead</li> </ul></li> </ul> <h3>update (abstraction):</h3> <pre><code>def extremeN [T](n: Int, li: List [T]) (comp1: ((T, T) =&gt; Boolean), comp2: ((T, T) =&gt; Boolean)): List[T] = { def updateSofar (sofar: List [T], el: T) : List [T] = if (comp1 (el, sofar.head)) (el :: sofar.tail).sortWith (comp2 (_, _)) else sofar (li.take (n) .sortWith (comp2 (_, _)) /: li.drop (n)) (updateSofar (_, _)) } /* still bound to Int: def top (n: Int, li: List [Int]) : List[Int] = { extremeN (n, li) ((_ &lt; _), (_ &gt; _)) } def bottom (n: Int, li: List [Int]) : List[Int] = { extremeN (n, li) ((_ &gt; _), (_ &lt; _)) } */ def top [T] (n: Int, li: List [T]) (implicit ord: Ordering[T]): Iterable[T] = { extremeN (n, li) (ord.lt (_, _), ord.gt (_, _)) } def bottom [T] (n: Int, li: List [T]) (implicit ord: Ordering[T]): Iterable[T] = { extremeN (n, li) (ord.gt (_, _), ord.lt (_, _)) } top (3, li) bottom (3, li) val sl = List ("Haus", "Garten", "Boot", "Sumpf", "X", "y", "xkcd", "x11") bottom (2, sl) </code></pre> <p>To replace List with Iterable seems to be a bit harder. </p> <p>As Daniel C. Sobral pointed out in the comments, a high <code>n</code> in topN can lead to much sorting work, so that it could be useful, to do a manual insertion sort instead of repeatedly sorting the whole list of top-n elements:</p> <pre><code>def extremeN [T](n: Int, li: List [T]) (comp1: ((T, T) =&gt; Boolean), comp2: ((T, T) =&gt; Boolean)): List[T] = { def sortedIns (el: T, list: List[T]): List[T] = if (list.isEmpty) List (el) else if (comp2 (el, list.head)) el :: list else list.head :: sortedIns (el, list.tail) def updateSofar (sofar: List [T], el: T) : List [T] = if (comp1 (el, sofar.head)) sortedIns (el, sofar.tail) else sofar (li.take (n) .sortWith (comp2 (_, _)) /: li.drop (n)) (updateSofar (_, _)) } </code></pre> <p>top/bottom method and usage as above. For small groups of top/bottom Elements, the sorting is rarely called, a few times in the beginning, and then less and less often over time. For example, 70 times with top (10) of 10 000, and 90 times with top (10) of 100 000. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload