javaの質問です。
mport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Answer{
public static void main(String[] args) throws IOException { int a,b,answer,sum=0,tmpnum=0; double avg=0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("一つ目の数字"); String str = br.readLine(); a = Integer.parseInt(str); System.out.println("二つ目の数字"); String str2 = br.readLine(); b = Integer.parseInt(str2); System.out.println("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); String c = br.readLine(); switch(c){
case "1":
case "Max":
case "2":
case "Min":
if(a <= b){ tmpnum = b; b = a; a = tmpnum; System.out.println(a); } if(c.equals("1") || c.equals("Max")){ answer = a; System.out.println(anser); } else{ answer= b; System.out.println(anser); } break;
結果としては
10
20
MAX
20
と言った流れです。
数値は2回だけ入力し区分のMAXor最大値の時と
MINor最小値で大きい数を出すか小さい数を出す
か判別するプログラムです。
上のプログラムではa.bの入力された数値を交換しているですが、先生からプログラムの再利用性
を考えてと言われよく分からない状態です。
最初に数値を2つ打たせ次の区分で最大値かMAXとキーボードから打たれたら数値の大きい方を表示し、最小値かMINだった場合は数値の小さい方を出すプログラムがあるとします。
2つのロジックは似たようなものになるので記述を再利用性を考えてまとめるとしたらどのようにコードを書いたらいいのでしょうか⁇
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
ベストアンサー
java.lang.Mathのmax()やmin()などを自分で実装するような感じにすればいいと思います。
Java
1import java.io.BufferedReader; 2import java.io.IOException; 3import java.io.InputStreamReader; 4 5public class Answer{ 6 7 static String readString(String caption) throws IOException { 8 System.out.println(caption); 9 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 10 return br.readLine(); 11 } 12 13 static int readInteger(String caption) throws IOException, NumberFormatException { 14 return Integer.parseInt(readString(caption)); 15 } 16 17 static int max(int a, int b) { 18 return a < b ? b : a; 19 } 20 21 static int min(int a, int b) { 22 return a < b ? a : b; 23 } 24 25 public static void main(String[] args) throws IOException, NumberFormatException { 26 int a = readInteger("一つ目の数字"); 27 int b = readInteger("二つ目の数字"); 28 String c = readString("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); 29 switch (c) { 30 case "1": 31 case "Max": 32 System.out.println(max(a, b)); 33 break; 34 case "2": 35 case "Min": 36 System.out.println(min(a, b)); 37 break; 38 } 39 } 40}
投稿2016/01/25 11:50
総合スコア2183
0
テストのしやすさも加味してみました。
ここでは、いくつかの例を main() 中に書いていますが、
junit でテストケースを書くのが本来のテストの書き方になります。
min, max だけでなく、average(平均), add(足し算), sub(引き算) などの
処理の追加もしやすくなることも考慮しています。
java
1// See https://teratail.com/questions/25569 2 3import java.io.BufferedReader; 4import java.io.IOException; 5import java.io.InputStreamReader; 6 7class Comp { 8 public int min(int a, int b) { 9 return (a < b) ? a : b; 10 } 11 12 public int max(int a, int b) { 13 return (a < b) ? b : a; 14 } 15 16 public int add(int a, int b) { 17 return a + b; 18 } 19 20 public int sub(int a, int b) { 21 return a - b; 22 } 23 24 public int calc(String func, int a, int b) { 25 switch (func) { 26 case "2": 27 case "min": 28 return min(a, b); 29 case "1": 30 case "max": 31 return max(a, b); 32 default: 33 throw new IllegalArgumentException(func); 34 } 35 } 36} 37 38public class Answer { 39 40 static String readString(String caption) throws IOException { 41 System.out.println(caption); 42 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 43 return br.readLine(); 44 } 45 46 static int readInteger(String caption) throws IOException, NumberFormatException { 47 return Integer.parseInt(readString(caption)); 48 } 49 50 public static void main(String[] args) throws IOException, NumberFormatException { 51 Comp comp = new Comp(); 52 53 int a = readInteger("一つ目の数字"); 54 int b = readInteger("二つ目の数字"); 55 String func = readString("区分を入力して下さい。(1 or Max:Max / 2 or Min:Min /)"); 56 System.out.println(comp.calc(func, a, b)); 57 58 // 簡易テスト 59 String[][] TESTS = { 60 { "max", "1", "2", "2" }, 61 { "max", "1", "1", "1" }, 62 { "1", "1", "2", "2" }, 63 { "min", "1", "2", "1" }, 64 { "min", "1", "1", "1" }, 65 { "2", "1", "2", "1" } 66 }; 67 for (String[] test : TESTS) { 68 int ans = comp.calc(test[0], Integer.parseInt(test[1]), Integer.parseInt(test[2])); 69 if (Integer.parseInt(test[3]) != ans) { 70 System.out.println("### Fail test:" + String.join(", ", test)); 71 } 72 } 73 } 74}
calc() 中の case 文はもっと工夫が可能です。
c/c++ での関数ポインターのようなものをにして
{"min" , finc_min} のように文字列の関数名と実際の java のメソッドを結びつけることで
case での分岐は、配列から関数名を探す処理に置き換えるのです。
投稿2016/01/31 15:06
総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
Stripeさんがご回答されたコードが秀逸です。
「再利用できるように」と言われても、何をどうすれば良いかイメージしずらいですよね。。。
以下のことを意識してみてください。
まず達成すべき処理がありますね。
「2つの数値と1つの文字の入力を受け、文字の区分によって最大値または最小値を出力する」
①この処理に必要であろう「単純な一つの仕事をする処理」を考えます。
おおむね、以下の機能があれば実装できそうですね。
・数値入力を受ける
・文字入力を受ける
・最大値を求める
・最小値を求める
②細分化したら、この機能のインターフェース(引数と戻り値)を考えます。
・数値入力を受ける機能 → 引数なし、数値を返却
・文字入力を受ける機能 → 引数なし、文字列を返却
・最大値を求める機能 → 引数は数値2つ、数値を返却
・最小値を求める機能 → 引数は数値2つ、数値を返却
インターフェースは内部の処理に関係ないデータまで含んだ配列やMapを渡すなど、
乱暴に設計してはいけません。
「必要なものを、必要なだけ」「できるだけ数値または文字列で」が指針の一つですが、そうはいかない
事も多々あります・・・
このように分析して、分解された「単純な一つの仕事をする処理」を、それぞれ実装します。
場合によっては、この処理単体でテストもします。
処理一つ一つがテストされて、ばっちり動くことが保障されたら、これらの機能を利用して、mainで目的の処理を記述します。
Stripeさんのコードは、まさにこのような書き方になっています。
よく細分化され、インターフェースがスッキリしていると、再利用性が高まります。
例えば、「数値入力を受ける」メソッドは、同じプログラムでまた入力が必要になった場合、
このメソッドを呼ぶだけですぐ再利用できます。
全く別のプログラム書くときは、参照して利用しても良いですし、コピペしたってそのまま使えます。
これは、各メソッドが「単純な一つの仕事をする処理」になっていて、かつ「インターフェースがスッキリ」しているからこそ成せるのです。
※前者を「凝集度」、後者を「結合度」という測り方で評価する方法があります。慣れてきたら勉強すると良いです。
この恩恵は再利用ができるだけではありません。
「単純な一つの仕事をする処理」に分けられていれば、メソッド名も付けやすくなります。
(メソッド名が付けずらい場合は、2つ以上の仕事がその中に入っている可能性が大です)
各メソッドが、このように単純な一つの仕事をする処理にスッキリとまとまっていると、
なにより、mainロジックの手続き処理の見通しが良くなります。
mainロジックの手続きがはっきり見通せるプログラムは、とっても読みやすいです。
そのため保守効率も、改修効率も上がります。
Stripeさんのコードをもう一度よくご覧になり、良く分析して理解されることをお勧めします。
投稿2016/01/25 17:04
編集2016/01/25 17:09総合スコア422
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
再利用のための、コードを書くためには、まず再利用ができないコードが書ける必要があります。慣れてくれば、書く前にどのようなコードになるかわかるので、再利用を意識したコードを直接書くようになります。慣れていない場合は、いきなり再利用できるようにすると余分なものまで再利用できるようにしてしまいますので順を追って再利用可能なコードに仕上げる必要があります。
始めは、再利用を考えずに書きます。
単純すぎますが、例えばこんなコードがあったとして
java
1int i = 2 + 1; 2System.out.println(i);
これがきちんと動作することが前提になります。
再利用したいコードがこうだっだとします。
java
1int j = 3 + 1; 2System.out.println(j);
違う部分を変数にします。
java
1int k = 2; 2int i = k + 1; 3System.out.println(i);
問題なく動作するか確認します。
これを関数に変えます。
java
1private void someMethod(int k){ 2 int i = k + 1; 3 System.out.println(i); 4}
このメソッドに名前を付けます。
そうですね、1を足してプリントするメソッドなので・・・
java
1private static void printAddOne(int k){ 2 int i = k + 1; 3 System.out.println(i); 4}
再利用します。
java
1printAddOne(2); 2printAddOne(3);
うまく動きますか?
足したものを表示するって、なんか分かりずらいですね。(と考えたとします。)
表示する部分はちゃんと見せたほうがわかりやすいかも・・・
java
1System.out.println(addOne(2)); 2System.out.println(addOne(3));
じゃあメソッドのほうも修正しましょう。
java
1private static int addOne(int k){ 2 int i = k + 1; 3 return i; 4}
また、動作を確認します。
このように、まず動くものを作ってちょっと修正して、確認してを繰り返すとだんだん再利用しやすいコードがかけるようになります。
投稿2016/01/25 10:50
編集2016/01/25 11:04総合スコア2883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
大きいほうを希望するのなら"最大値"か"MAX"、小さいほうを希望するのなら"最小値"か"MIN"と入力させるのでしょうか??
標準入力等で入力するのは
"数値1" "数値2" "最大値/MAX/最小値/MIN"
ということですかね??
あまり長い処理にはならないと思うので記述の再利用性・・・というのもなんですが、
↑のように入力されるとしたら、↓をメソッド化して
long ans = 0; if(args[2]が"最大値"または"MAX"){ ans = Math.max()で比較 }else if(args[2]が"最小値"または"MIN"){ ans = Math.min()で比較 } ans を出力
みたいな感じでしょうか。
適宜、入力値チェックや型変換などを行ってください。
投稿2016/01/25 05:28
総合スコア1844
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/01/25 05:43
0
こんにちは。
コンソールからの入力になるので、入力文字は全てstring型で受け取れます。
したがって、以下のようなメソッドを作って対応してみてはいかがでしょう?
数値に限らず、引数で渡した文字列を辞書順で比較し、小さいほう又は大きいほうを受け取れます。
※数字だけに限らず、文字列も大小を判別できるので、やや汎用的かな?
public static String returnMinValue( String val1 , String val2 ){
if( val1.compareTo( val2 ) < 0 ){
return val2;
}else{
return val1;
}
}
public static String returnMaxValue( String val1 , String val2 ){
if( val1.compareTo( val2 ) < 0 ){
return val1;
}else{
return val2;
}
}
case:"1"
case:"Max"
に対しては、returnMaxValueを。
case:"2"
case:"Min"
に対しては、returnMinValueを。
いかがでしょう?
※caseの区切りにbreak;するのを忘れないでね!
あと、入力チェックが実装されていないようなので、
余力があれば入れてみてください。
※1,Max,2,Min以外の入力があった場合への対応など。
投稿2016/01/25 05:06
編集2016/01/25 05:30総合スコア94
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/01/25 05:40
2016/01/25 11:39
2016/01/26 01:14
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。