scala関西ビギナーズ

32
Scalaで クイックソートを 書いてみよう 2014-02-08 第3回 Scala関西ビギナーズ 1428日土曜日

Upload: daisuke-kasuya

Post on 24-May-2015

1.768 views

Category:

Technology


3 download

DESCRIPTION

第3回Scala関西ビギナーズ発表資料

TRANSCRIPT

Page 1: Scala関西ビギナーズ

Scalaでクイックソートを書いてみよう

2014-02-08 第3回 Scala関西ビギナーズ14年2月8日土曜日

Page 2: Scala関西ビギナーズ

自己紹介

14年2月8日土曜日

Page 3: Scala関西ビギナーズ

自己紹介

粕谷 大輔

Twitter: @daiksy

フリュー株式会社

14年2月8日土曜日

Page 4: Scala関西ビギナーズ

自己紹介

電子書籍

『開発現場に伝えたい10のこと』

達人出版会 500円

14年2月8日土曜日

Page 5: Scala関西ビギナーズ

アルゴリズム

ソート

探索

リストスタック & キュー

再帰

ツリー

ハッシュ

動的計画法14年2月8日土曜日

Page 6: Scala関西ビギナーズ

アルゴリズム

新しい言語を学ぶ際に

時々振り返ると

いろいろ気づくことがある

14年2月8日土曜日

Page 7: Scala関西ビギナーズ

今回はクイックソートを見てみる

14年2月8日土曜日

Page 8: Scala関西ビギナーズ

L Q C A K B I J F R H D N T E O S G M P

14年2月8日土曜日

Page 9: Scala関西ビギナーズ

L Q C A K B I J F R H D N T E O S G M PL

pivotを決める

14年2月8日土曜日

Page 10: Scala関西ビギナーズ

L Q C A K B I J F R H D N T E O S G M PL

LC A K B I J F H D E G Q R N T O S M P

pivotより小さいグループと

大きいグループに分ける

14年2月8日土曜日

Page 11: Scala関西ビギナーズ

L Q C A K B I J F R H D N T E O S G M PL

LC A K B I J F H D E G Q R N T O S M P

繰り返す

C QK I J F H D E GA B L O PR N T SM

QC

14年2月8日土曜日

Page 12: Scala関西ビギナーズ

まずはJavaだとこう書ける

14年2月8日土曜日

Page 13: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 14: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

listの先頭をpivotとし、それ以外のlistを取り出す

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 15: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

pivot以下のグループ

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 16: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

pivotより大きいグループ

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 17: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

pivot以下のグループ、pivot、

pivotより大きいグループそれぞれを再帰的に連結

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 18: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 19: Scala関西ビギナーズ

public class QuickSort {

public static List<Integer> sort(List<Integer> list) { if (list.isEmpty()) { return list; }

Integer pivot = list.get(0); List<Integer> listWithoutPivot = list.subList(1, list.size());

List<Integer> leftSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem <= pivot) { leftSide.add(elem); } }

List<Integer> rightSide = new LinkedList<>(); for (Integer elem : listWithoutPivot) { if (elem > pivot) { rightSide.add(elem); } }

List<Integer> result = new ArrayList<>(); result.addAll(sort(leftSide)); result.add(pivot); result.addAll(sort(rightSide));

return result; }}

ちゃんと読めば意図を理解できるけど、ぱっと見ではわかりづらくないですか?

参考: http://nikcode.blogspot.jp/2013/10/quick-sort-scala-vs-java.html14年2月8日土曜日

Page 20: Scala関西ビギナーズ

さて、Scalaで書くとこうなる

14年2月8日土曜日

Page 21: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

14年2月8日土曜日

Page 22: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

listの先頭をpivotとし、それ以外のlistを取り出す

14年2月8日土曜日

Page 23: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

pivot以下のグループ

14年2月8日土曜日

Page 24: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

pivotより大きいグループ

14年2月8日土曜日

Page 25: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

pivot以下のグループ、pivot、

pivotより大きいグループそれぞれを再帰的に連結

14年2月8日土曜日

Page 26: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

14年2月8日土曜日

Page 27: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

直感的な気がする!!!

14年2月8日土曜日

Page 28: Scala関西ビギナーズ

def qSort[T <% Ordered[T]](data: List[T]): List[T] = { data match { case Nil => data case x::xs => { qSort(xs.filter(_ <= x)) ++ List(x) ++ qSort(xs.filter(x < _)) } }} 

実はこれ、末尾再帰じゃないのでわりとすぐにスタックオーバーフロー!!

CAUTION!!

14年2月8日土曜日

Page 29: Scala関西ビギナーズ

まとめ:Scalaで再帰を使って書くと手続き的に書くより直感的に書ける(事がよくある)。

14年2月8日土曜日

Page 30: Scala関西ビギナーズ

宣伝

14年2月8日土曜日

Page 31: Scala関西ビギナーズ

dmm4s

https://github.com/daiksy/dmm4s14年2月8日土曜日

Page 32: Scala関西ビギナーズ

ご清聴ありがとうございました

14年2月8日土曜日