240 likes | 349 Views
クイックソート. 1. 実習1. personal_info 構造体の分類. personal_info 構造体のリスト alop と, personal_info 構造体 pivot を入力として, alop から 「 name 属性の値が, pivot の name 属性よりも辞書順で 大きい もの」を選んで,リストを出力する関数 larger-items を定義し,実行する リストの要素を1つずつ調べる. larger-iterms 関数の入力と出力. alop の値: (list
E N D
クイックソート 1
実習1.personal_info 構造体の分類 • personal_info構造体のリスト alopと, personal_info構造体 pivotを入力として,alopから 「name属性の値が,pivotの name属性よりも辞書順で大きいもの」を選んで,リストを出力する関数 larger-itemsを定義し,実行する • リストの要素を1つずつ調べる
larger-iterms 関数の入力と出力 alopの値: (list (make-personal_info "Mike" 10 "Fukuoka") (make-personal_info "Bill" 20 "Saga") (make-personal_info "Ken" 30 "Nagasaki")) pivotの値: (make-personal_info "John" 25 "Kumamoto")) 入力 出力 larger-iterms 入力はpersonal_info 構造体のリストと, personal_info 構造体 入力はpersonal_info 構造体のリスト (list (make-personal_info "Mike" 10 "Fukuoka") (make-personal_info "Ken" 30 "Nagasaki"))
personal_info 構造体 personal_info構造体の定義 構造体名 フィールド名の並び (define-struct personal_info (name age address)) 上記の定義によって以下が使えるようになる • コンストラクタ (make-personal_info 値値値) • セレクタ (personal_info-name …) (personal_info-age …) (personal_info-address …) • personal_infoかを調べる (personal_info? …) personal_info フィールド
実習1の手順 • 次を「定義用ウインドウ」で,定義しなさい • 入力した後に,Run ボタンを押す (define-struct personal_info (name age address)) (define (larger-itemsalop pivot) (cond [(empty? alop) empty] [else (cond [(string>=? (personal_info-name (first alop)) (personal_info-name pivot)) (cons (first alop) (larger-items (rest alop) pivot))] [else (larger-items (rest alop) pivot)])])) (define book (list (make-personal_info "Mike" 10 "Fukuoka") (make-personal_info "Bill" 20 "Saga") (make-personal_info "Ken" 30 "Nagasaki")))
実習1の手順 • その後,次を「実行ウインドウ」で実行しなさい (larger-items book (make-personal_info "John" 25 "Kumamoto"))
実習2.personal_info 構造体の分類2 • personal_info構造体のリスト alopと, personal_info構造体 pivotを入力として,alopから 「name属性の値が,pivotの name属性よりも辞書順で小さいもの」を選んで,リストを出力する関数 smaller-itemsを定義し,実行する • リストの要素を1つずつ調べる
実習2の手順 • 次を「定義用ウインドウ」で,定義しなさい • 入力した後に,Run ボタンを押す 実習1からの変更点 は4箇所 (define-struct personal_info (name age address)) (define (smaller-itemsalop pivot) (cond [(empty? alop) empty] [else (cond [(string<=? (personal_info-name (first alop)) (personal_info-name pivot)) (cons (first alop) (smaller-items (rest alop) pivot))] [else (smaller-items (rest alop) pivot)])])) (define book (list (make-personal_info "Mike" 10 "Fukuoka") (make-personal_info "Bill" 20 "Saga") (make-personal_info "Ken" 30 "Nagasaki")))
実習2の手順 • その後,次を「実行ウインドウ」で実行しなさい (smaller-items book (make-personal_info "John" 25 "Kumamoto"))
実習3.辞書順を判定する関数 • 2つの personal_info構造体 x,yを入力とし, xが y よりも辞書順で前にあるかを調べる関数 is-smallerを定義し,実行する • is-smaller 関数は,実習6で使用する
Contract (規約) ;; is-smaller: personal_info personal_info -> boolean personal_info 構造体 personal_info 構造体 ブール値 出力 入力
実習3の手順 • 次を「定義用ウインドウ」で,定義しなさい • 入力した後に,Run ボタンを押す (define-struct personal_info (name age address)) ;; is-smaller: personal_info personal_info -> boolean (define (is-smallerx y) (cond [(not (personal_info? x)) false] [(not (personal_info? y)) false] [(string>=? (personal_info-name x) (personal_info-name y)) false] [else true]))
実習3の手順 • その後,次を「実行ウインドウ」で実行しなさい (is-smaller (make-personal_info "John" 25 "Kumamoto") (make-personal_info "Ken" 30 "Nagasaki")) (is-smaller (make-personal_info "John" 25 "Kumamoto") (make-personal_info "Bill" 20 "Saga"))
実習4.クイックソート Hoare のクイックソートのアルゴリズムを使ったプログラム quick-sortを作る. • この実習では,personal_info構造体を昇順にソートする • リストの分割では,「 7.設計の抽象化」で登場した高階関数filter1を使う • リストの結合には,実習1の append関数を使う quick-sort 入力は personal_info構造体のリスト 出力は personal_info構造体のリスト
クイックソートの例(数値の場合) リスト 8 10 6 3 5 分割:基底ケー ス(リストが空)に なるまで pivot の 選択と pivot によ るリストの分割を 繰返す(再帰) 先頭を pivot に pivot より大 8 pivotより小 10 6 3 5 pivot pivot 6 10 3 5 empty empty empty 以下省略 省略 統合:(再帰呼出 による) 中間結果 と pivot のリストを 順序を保存し結合 3 5 6 empty empty 10 empty 8 10 3 5 6 3 5 6 8 10
Contract (規約) filter関数の新しい Contract(規約) 「 7.設計の抽象化」の回では,X の部分は「number」だった filter1: (X X -> boolean) (listof X) X -> (listof X) 関数 入力:2つの X 出力:boolean Xのリスト X Xのリスト 出力 入力 Xは型変数
実習4の手順 (1/3) • 次を「定義用ウインドウ」で,定義しなさい • 入力した後(次ページも)に,Run ボタンを押す (define-struct personal_info (name age address)) ;; is-smaller: personal_info personal_info -> boolean (define (is-smallerx y) (cond [(not (personal_info? x)) false] [(not (personal_info? y)) false] [(string>=? (personal_info-name x) (personal_info-name y)) false] [else true])) ;; is-larger: personal_info personal_info -> boolean (define (is-largerx y) (cond [(not (personal_info? x)) false] [(not (personal_info? y)) false] [(string<=? (personal_info-name x) (personal_info-name y)) false] [else true])) 実習5と同じ
実習4の手順 (2/3) ;;filter1: (X X -> boolean) (listof X) X -> (listof X) (define (filter1rel_op alon t) (cond [(empty? alon) empty] [else (cond [(rel_op (first alon) t) (cons (first alon) (filter1rel_op (rest alon) t))] [else (filter1rel_op (rest alon) t)])])) ;; quick-sort : (listof personal_info) -> (listof personal_info) ;; to create a list as alop sorted in ascending order (define (quick-sortalop) (cond [(empty? alop) empty] [else (append (quick-sort (filter1is-smalleralop (first alop))) (list (first alop)) (quick-sort (filter1is-larger alop (first alop))))]))
実習4の手順 (3/3) • その後,次を「実行ウインドウ」で実行しなさい (define address (list (make-personal_info "Mike" 10 "Fukuoka") (make-personal_info "Bill" 20 "Saga") (make-personal_info "Ken" 30 "Nagasaki") (make-personal_info "John" 25 "Kumamoto"))) (quick-sort address)
Name Price Category Publisher Harry Potter $17.99 Children Levine Books 1776 $21.12 History Simon & Schuster Freakonomics $15.57 Business William Morrow Eleven on Top $17.79 Mystery St. Martin's Press The Da Vinci Code $14.97 Mystery Doubleday Winning $15.51 Business HarperBusiness 課題1.クイックソート • 下記のデータについての問題 • 「Price > 16」 を満足するものを取り出す関数を定義し,実行結果を報告しなさい • 「Price > 16」 を満足するものを,price の順でソートして取り出す関数を定義し,実行結果を報告しなさい