計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

山元進.  for 文  while 文  do ~ while 文  文のネスト  break 文  continue 文.
2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
アルゴリズムとデータ構造 2012年6月27日
プログラミング基礎I(再) 山元進.
アルゴリズムとデータ構造1 2005年7月8日
~手続き指向からオブジェクト指向へ(Ⅰ)~
プログラミング基礎I(再) 山元進.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング基礎I(再) 山元進.
第2回ネットワークプログラミング 中村 修.
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
繰り返し プログラミング 第4回 繰り返し プログラミング第4回.
関数 関数とスタック.
計算機プログラミングI 第8回 2002年12月5日(木) メソッドとクラス (教科書6章) クイズ インスタンスメソッド インスタンス変数
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
プログラミング言語入門 手続き型言語としてのJava
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
独習Javaゼミ第10回 セクション1~3 発表者 直江 宗紀.
ソフトウェア制作論 平成30年10月24日.
ソフトウェア制作論 平成30年10月31日.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
再帰的手続き.
計算機プログラミングI 第5回 配列 文字列(Stringクラス) mainの引数 配列の利用例
演習07-0 “Hello\n” “World!\n”と
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
計算機プログラミングI 第6回 2002年11月14日(木) アルゴリズムと計算量 第1回課題の説明 平方根を計算するアルゴリズム 計算量
アルゴリズムとプログラミング (Algorithms and Programming)
補講:アルゴリズムと漸近的評価.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとプログラミング (Algorithms and Programming)
Chapter 5 5.5 thisキーワード 5.6 インスタンス変数とインスタンスメソッド 結城 隆
高度プログラミング演習 (11).
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年6月25日
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向 プログラミング 第四回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
演習00-0 “Hello\n” “World!\n”と
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
モバイルプログラミング第2回 C言語の基礎 (1).
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
ねらい 数値積分を例題に、擬似コードのアルゴリズムをプログラムにする。
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
知能情報工学演習I 第10回( C言語第4回) 課題の回答
プログラミング演習I 補講用課題
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数 (素因数分解) 曜日の計算 クラスメソッドと手続きの抽象化

問題解決とアルゴリズム アルゴリズム: 問題を解くための手順 問題 アルゴ リズム アルゴ リズム アルゴ リズム C++ Java プログラム

問題解決の方法 問題 問題の分割・・・ 問題 問題 問題 アルゴリズムの 考案・当てはめ アルゴ リズム アルゴ リズム プログラム /** 2002年10月31日の曜日を計算する */ public class WeekdayMethods { public static void main(String[] args) { int dayOfWeek = days%7; // 0:日曜日 .. 6:土曜日 int days = countDays(); // 1900年1月1日から目的の日までの日数を計算し、daysに代入 } System.out.println("曜日は"+dayOfWeek); public static int countDays() { /** 1900年1月1日から目的の日までの日数 */ int d = 0; loop: // year年month月の日数を計算しdaysOfMonthに代入 for (int month = 1; month <= 12; month++) { for (int year = 1900; year <= 2002; year++) { int daysOfMonth = daysOfMonth(year,month); for (int date = 1; date <= daysOfMonth; date++) { if (year==2002 && month==10 && date == 31) // 目的の日になったら繰返し全体を終了する d++; break loop; // 4.5節参照 return d; // 数えた日数を返す public static int daysOfMonth(int y, int m) { /** y年m月の日数 */ int days; if (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12) days = 30; // 小の月 else if (m==4 || m==6 || m==9 || m==11) days = 31; // 大の月 days = 29; // 閏年の2月 else if (isLeapYear(y)) days = 28; // 平年の2月 else return days; // 月の日数を返す public static boolean isLeapYear(int y) { /** y年は閏年か */ return y%400 == 0 || (y%100 != 0 && y%4 == 0); プログラム

最大公約数 問題: 2つの整数a, bの最大公約数を求める (ただし a < b) 問題の分割: アルゴリズム1: 公約数かどうかを調べる 最大の公約数を求める アルゴリズム1: i を 1, 2, ..., a の順に変化 i が a, b の公約数であるかを調べる 最後に公約数であると分かったときの i の値が最大公約数

アルゴリズム1 a=6, b=21の場合 i=1: i は a,bの公約数である i=2: i は a,bの公約数でない → 3が最大公約数

アルゴリズム1のプログラム iはaの約数 && iはbの約数 a%i == 0 public class GCD { public static void main(String[] args){ int a = 12, b = 21; int lastCommonDivisor = 0; // 一番最近に見つかった公約数 for (int i = 1; i <= a; i++) { if (iはa,bの公約数?) { lastCommonDivisor = i; // iは公約数なので覚える } System.out.println(lastCommonDivisor); iはaの約数 && iはbの約数 a%i == 0

アルゴリズム2 逆順に探す i=6: i は a,bの公約数でない i=5: i は a,bの公約数でない → 3が最大公約数

アルゴリズム2のプログラム public class GCD2 { public static void main(String[] args){ int a = 12, b = 21; int i = a; while (! iはa,bの公約数) i--; System.out.println("最大公約数は" + i); }

ユークリッドの互除法 定理: bをaで割った余りをrとする aとbの最大公約数とrとaの最大公約数は等しい アルゴリズム: rが0でない: r,aの最大公約数を求める rで0である: aが最大公約数

アルゴリズムによって繰返しの回数が 大きく違う ユークリッドの互除法 アルゴリズムによって繰返しの回数が 大きく違う 例:a=143, b=1469 の場合 余りが0になったときのaが最大公約数

ユークリッドの互除法:プログラム (略) 今回のa,(b/aの余り)を次回のb,aに ―― 注意が必要

素因数分解 問題の分割 素因数を1つ見つける 素因数を全て見つける (資料参照)

曜日の計算 問題:2002年10月31日は何曜日 アルゴリズム: 小問題:基準日から目的日までの 日数を数える 小問題: y年m月の日数 基準となる日から 目的の日までの日数を数える 7で割った余りを求める 小問題:基準日から目的日までの 日数を数える 年を基準~目的まで変化 月を1~12まで変化 日を1~(月の日数)まで変化 日数を1増やし 目的日になったら終了 小問題: y年m月の日数 アルゴリズム: mが大の月: 31 日 mが小の月(2月以外): 30日 mが2月: yが閏年: 29日 yが平年: 28日 小問題: y年が閏年か調べる yが400の倍数、または yが100の倍数でなく4の倍数

曜日を計算するプログラム 基準となる日から 目的の日までの日数を数える y年m月の日数 y年が閏年か調べる 7で割った余りを求める /** 2002年10月31日の曜日を計算する */ public class Weekday { public static void main(String[] args) { int days = 0; // 1900年1月1日から目的の日までの日数を計算し、daysに代入 loop: for (int year = 1900; year <= 2002; year++) { for (int month = 1; month <= 12; month++) { int daysOfMonth; // year年month月の日数を計算しdaysOfMonthに代入 if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) daysOfMonth = 31; else if (month==4 || month==6 || month==9 || month==11) daysOfMonth = 30; /* 2月の場合、閏年かどうかを調べる (練習問題3.6-2) */ else if (year%400 == 0 || (year%100 != 0 && year%4 == 0)) daysOfMonth = 29; // 閏年 else daysOfMonth = 28; // 平年 基準となる日から 目的の日までの日数を数える y年m月の日数 y年が閏年か調べる for (int date = 1; date <= daysOfMonth; date++) { days++; // 目的の日になったら繰返し全体を終了する if ((year==2002) && (month==10) && (date == 31)) break loop; // 4.5節参照 } int dayOfWeek = days%7; // 0:日曜日 .. 6:土曜日 System.out.println("曜日は"+dayOfWeek); 7で割った余りを求める

練習

クラスメソッド 問題を分割――プログラムは分割されていない → クラスメソッドを使うと分割できる

クラスメソッドによる プログラムの分割 /** 2002年10月31日の曜日を計算する */ public class Weekday { public static void main(String[] args) { // 1900年1月1日から目的の日までの日数を計算し、daysに代入 int days = Weekday.countDays(); int dayOfWeek = days%7; // 0:日曜日 .. 6:土曜日 System.out.println("曜日は"+dayOfWeek); } /** 1900年1月1日から目的の日までの日数 */ public static int countDays() { int d = 0; loop: for (int year = 1900; year <= 2002; year++) { for (int month = 1; month <= 12; month++) { // year年month月の日数を計算しdaysOfMonthに代入 int daysOfMonth = Weekday.daysOfMonth(year,month); for (int date = 1; date <= daysOfMonth; date++) { d++; // 目的の日になったら繰返し全体を終了する if (year==2002 && month==10 && date == 31) break loop; // 4.5節参照 return d; // 数えた日数を返す /** y年m月の日数 */ public static int daysOfMonth(int y, int m) { int days; if (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12) days = 31; // 大の月 else if (m==4 || m==6 || m==9 || m==11) days = 30; // 小の月 else if (Weekday.isLeapYear(y)) days = 29; // 閏年の2月 else days = 28; // 平年の2月 return days; // 月の日数を返す } /** y年は閏年か */ public static boolean isLeapYear(int y) { return y%400 == 0 || (y%100 != 0 && y%4 == 0);

クラスメソッドの定義 クラス メソッドの呼出し 引数の個数と型 クラス メソッドの定義 クラスメソッド であることを示す キーワード /** 2002年10月31日の曜日を計算する */ public class Weekday { public static void main(String[] args) { // 1900年1月1日から目的の日までの日数を計算し、daysに代入 int days = Weekday.countDays(); int dayOfWeek = days%7; // 0:日曜日 .. 6:土曜日 System.out.println("曜日は"+dayOfWeek); } /** 1900年1月1日から目的の日までの日数 */ public static int countDays ( ) { int d = 0; loop: for (int year = 1900; year <= 2002; year++) { for (int month = 1; month <= 12; month++) { // year年month月の日数を計算しdaysOfMonthに代入 int daysOfMonth = Weekday.daysOfMonth(year,month); for (int date = 1; date <= daysOfMonth; date++) { d++; // 目的の日になったら繰返し全体を終了する if (year==2002 && month==10 && date == 31) break loop; // 4.5節参照 return d; // 数えた日数を返す クラス メソッドの呼出し 引数の個数と型 クラス メソッドの定義 クラスメソッド であることを示す キーワード 返り値の型 (=答えは整数) 名前

メソッドの返り値 メソッド呼出し式の 値になる dの値を計算 public static void main(String[] args) { // 1900年1月1日から目的の日までの日数を計算し、daysに代入 int days = Weekday.countDays(); int dayOfWeek = days%7; // 0:日曜日 .. 6:土曜日 System.out.println("曜日は"+dayOfWeek); } /** 1900年1月1日から目的の日までの日数 */ public static int countDays() { int d = 0; loop: for (int year = 1900; year <= 2002; year++) { ... return d; // 数えた日数を返す メソッド呼出し式の 値になる dの値を計算

クラスメソッドの引数 引数を計算 (year,monthの値をとり出す) メソッドに渡す 引数が2つ 整数型 yとmにしまう /** 1900年1月1日から目的の日までの日数 */ public static int countDays() { int d = 0; loop: for (int year = 1900; year <= 2002; year++) { for (int month = 1; month <= 12; month++) { // year年month月の日数を計算しdaysOfMonthに代入 int daysOfMonth = Weekday.daysOfMonth(year,month); for (int date = 1; date <= daysOfMonth; date++) { d++; // 目的の日になったら繰返し全体を終了する if (year==2002 && month==10 && date == 31) break loop; // 4.5節参照 } return d; // 数えた日数を返す /** y年m月の日数 */ public static int daysOfMonth(int y, int m) { int days; if (m==1 || m==3 || m==5 || m==7 || m==8 || m==10 || m==12) days = 31; // 大の月 else if (m==4 || m==6 || m==9 || m==11) days = 30; // 小の月 else if (Weekday.isLeapYear(y)) days = 29; // 閏年の2月 else days = 28; // 平年の2月 return days; // 月の日数を返す } 引数が2つ 整数型 yとmにしまう

クラスメソッドのまとめ 呼出す側で引数の値が 計算される 呼出される側の変数に 引数がしまわれる 呼出された側が実行 return文の式の値が 計算される 返り値が呼出した側の 式の値になる 呼出した側の実行が再開 呼出す側 x = Weekday.daysOfMonth(year,month)-1; x year month 31 2002,8 呼出される側 public static int daysOfMonth(int y, int m) { int d; ... return d; } d y m 変数は別々!

練習