scala関西ビギナーズ
DESCRIPTION
第3回Scala関西ビギナーズ発表資料TRANSCRIPT
Scalaでクイックソートを書いてみよう
2014-02-08 第3回 Scala関西ビギナーズ14年2月8日土曜日
自己紹介
14年2月8日土曜日
自己紹介
粕谷 大輔
Twitter: @daiksy
フリュー株式会社
14年2月8日土曜日
自己紹介
電子書籍
『開発現場に伝えたい10のこと』
達人出版会 500円
14年2月8日土曜日
アルゴリズム
ソート
探索
リストスタック & キュー
再帰
ツリー
ハッシュ
動的計画法14年2月8日土曜日
アルゴリズム
新しい言語を学ぶ際に
時々振り返ると
いろいろ気づくことがある
14年2月8日土曜日
今回はクイックソートを見てみる
14年2月8日土曜日
L Q C A K B I J F R H D N T E O S G M P
14年2月8日土曜日
L Q C A K B I J F R H D N T E O S G M PL
pivotを決める
14年2月8日土曜日
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日土曜日
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日土曜日
まずはJavaだとこう書ける
14年2月8日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
さて、Scalaで書くとこうなる
14年2月8日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
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日土曜日
まとめ:Scalaで再帰を使って書くと手続き的に書くより直感的に書ける(事がよくある)。
14年2月8日土曜日
宣伝
14年2月8日土曜日
dmm4s
https://github.com/daiksy/dmm4s14年2月8日土曜日
ご清聴ありがとうございました
14年2月8日土曜日