java初心者です。
forの繰り返しについての質問です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
この問題、面白いですね。
先の回答で挙げさせて頂きました
RhombusN2
を以下の2点を満たすように修正できないか考えました。
(1) for()のカッコの中と、アスタリスクにするときの if()のカッコの中だけを修正
(2) if()のカッコの中を、|| を使わない端的なものにする。
それで、以下ができました。
lang
1package question9524; 2 3import java.util.Scanner; 4 5public class RhombusN3 { 6 public static void main(String args[]) { 7 8 System.out.print("一辺の長さを入力して下さい。:"); 9 10 Scanner scan = new Scanner(System.in); 11 int n = scan.nextInt(); 12 scan.close(); 13 14 //縦 15 for(int y = n-1; y >= -(n-1) ; y -- ){ 16 //横 17 for(int x = -(n-1); x <= n-1; x ++ ){ 18 //条件 19 if( Math.abs(x) + Math.abs(y) == n-1 ){ 20 System.out.print("*"); 21 } else { 22 System.out.print(" "); 23 } 24 } 25 System.out.print("\n"); 26 } 27 } 28}
lang
1MGX82JA:bin ykt68$ java question9524.RhombusN3 2一辺の長さを入力して下さい。:1 3* 4MGX82JA:bin ykt68$ java question9524.RhombusN3 5一辺の長さを入力して下さい。:5 6 * 7 * * 8 * * 9 * * 10* * 11 * * 12 * * 13 * * 14 * 15MGX82JA:bin ykt68$ java question9524.RhombusN3 16一辺の長さを入力して下さい。:12 17 * 18 * * 19 * * 20 * * 21 * * 22 * * 23 * * 24 * * 25 * * 26 * * 27 * * 28* * 29 * * 30 * * 31 * * 32 * * 33 * * 34 * * 35 * * 36 * * 37 * * 38 * * 39 * 40MGX82JA:bin ykt68$
ひし形の2本の対角線が直交する交点の座標を(0,0)としてXY座標を考えると、
アスタリスクにする座標(x,y)では、
lang
1Math.abs(x) + Math.abs(y) == n-1
が成り立ちます。
方眼紙か何かで描いてみると分かり易いです。
ちなみにターミナルで実行するとひし形に見えますが、
座標上に点を打つと考えると、出来上がるのは正方形
ですね。
投稿2015/05/07 15:23
編集2015/05/08 00:04総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
では、私も一つ。
学校の課題っぽいですね。
楽しそうなので私もやってみました。
lang
1import java.util.Scanner; 2import java.lang.Math; 3public class Rhombus { 4 public static void main(String args[]) { 5 System.out.print("菱形の1辺の長さは?:"); 6 int x = 0; 7 while(x == 0){ 8 Scanner scan = new Scanner(System.in); 9 String str = scan.next(); 10 try { 11 x = Integer.parseInt(str); 12 break; 13 } catch (NumberFormatException nfex) { 14 System.out.print("整数を入力してね。:"); 15 } 16 } 17 int y = x - 1; 18 int n = (x * 2) - 1; 19 //縦 20 for(int i = 0; i < n; i++){ 21 //横 22 for(int j = 0; j < n; j++){ 23 //条件 24 if(Math.abs(i - j) == y || y - j == i || (y) * 2 - i + (y) == j){ 25 System.out.print("*"); 26 } else { 27 System.out.print(" "); 28 } 29 } 30 System.out.print("\n"); 31 } 32 } 33}
lang
1C:\java>java Rhombus 2菱形の1辺の長さは?:1 3* 4 5C:\java>java Rhombus 6菱形の1辺の長さは?:2 7 * 8* * 9 * 10 11C:\java>java Rhombus 12菱形の1辺の長さは?:3 13 * 14 * * 15* * 16 * * 17 * 18 19C:\java>java Rhombus 20菱形の1辺の長さは?:4 21 * 22 * * 23 * * 24* * 25 * * 26 * * 27 * 28 29C:\java>java Rhombus 30菱形の1辺の長さは?:5 31 * 32 * * 33 * * 34 * * 35* * 36 * * 37 * * 38 * * 39 *
投稿2015/05/07 14:35
総合スコア67
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
再び、こんにちは。
質問にある、辺の長さ5の場合のコードの
lang
1if( i + j == 6 || j - i == 4 || i - j == 4 || i + j == 14){
は、辺の長さが n のときは
lang
1if( i + j == n+1 || j - i == n-1 || i - j == n-1 || i + j == 3*n-1 ){
でした。なので、元のコードに出てくる具体的な数値(10,6,4,14)を入力された値で
置き換えたバージョンは、以下で良さそうです。
lang
1package question9524; 2 3import java.util.Scanner; 4 5public class RhombusN2 { 6 public static void main(String args[]) { 7 8 System.out.print("一辺の長さを入力して下さい。:"); 9 10 Scanner scan = new Scanner(System.in); 11 int n = scan.nextInt(); 12 scan.close(); 13 14 //縦 15 for(int i = 1; i < 2*n; i++){ 16 //横 17 for(int j = 1; j < 2*n; j++){ 18 //条件 19 if( i + j == n+1 || j - i == n-1 || i - j == n-1 || i + j == 3*n-1 ){ 20 System.out.print("*"); 21 } else { 22 System.out.print(" "); 23 } 24 } 25 System.out.print("\n"); 26 } 27 } 28}
自分もテストしてみました。
lang
1MGX82JA:bin ykt68$ java question9524.RhombusN2 2一辺の長さを入力して下さい。:1 3* 4MGX82JA:bin ykt68$ java question9524.RhombusN2 5一辺の長さを入力して下さい。:5 6 * 7 * * 8 * * 9 * * 10* * 11 * * 12 * * 13 * * 14 * 15MGX82JA:bin ykt68$ java question9524.RhombusN2 16一辺の長さを入力して下さい。:12 17 * 18 * * 19 * * 20 * * 21 * * 22 * * 23 * * 24 * * 25 * * 26 * * 27 * * 28* * 29 * * 30 * * 31 * * 32 * * 33 * * 34 * * 35 * * 36 * * 37 * * 38 * * 39 * 40MGX82JA:bin ykt68$
投稿2015/05/07 14:01
編集2015/05/07 23:47総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/05/09 03:34
0
lang
1import java.util.Scanner; 2 3public class Rhombus{ 4 public static void main(String args[]) { 5 6 System.out.println("整数を入力してください。"); 7 Scanner in = new Scanner(System.in); 8 int x = in.nextInt(); 9 10 for (int i = 0; i < x * 2 - 1; i++) { 11 for (int j = 0; j < x * 2 - 1; j++) { 12 System.out.print(cond(x, i, j)); 13 } 14 System.out.print("\n"); 15 } 16 } 17 static String cond(int len, int x, int y) { 18 int lenx = len - 1; 19 if (Math.abs(x - lenx) + Math.abs(y - lenx) == lenx) { 20 return "*"; 21 } 22 return " "; 23 } 24}
実行例:
$ java Rhombus 整数を入力してください。 1 * $ java Rhombus 整数を入力してください。 2 * * * * $ java Rhombus 整数を入力してください。 3 * * * * * * * * $ java Rhombus 整数を入力してください。 4 * * * * * * * * * * * *
平面上で
xx + yy = r *2 は 中心が (0, 0), 半径 r の 円 (circle) を表します。
abx(x) + abas(y) = r は 中心が (0, 0), 一片の長さ r の四角を表します。
↑の java コードでは、中心を (r, r) にずらしてこの四角を描くという方法をとっています。
投稿2015/05/07 13:27
編集2015/05/07 21:49総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
再び、こんにちは。
Scanner を使って標準入力から辺の長さを指定する場合、
先に挙げたコードで、args[0]から n を求めている以下の部分:
lang
1 // 引数のチェック 2 if (args.length > 0) { 3 try { 4 n = Integer.parseInt(args[0]); 5 } catch (NumberFormatException nfe) { 6 System.err.println("与えられた引数は整数に変換できません。"); 7 System.exit(1); 8 } 9 }
を、以下
lang
1 // Scannerから一辺の長さを取得する 2 System.out.print("一辺の長さを入力して下さい。:"); 3 4 Scanner scan = new Scanner(System.in); 5 try { 6 n = Integer.parseInt(scan.next()); 7 } catch (NoSuchElementException nsee) { 8 System.out.println("\r辺の指定がなかったので、" 9 + "デフォルト値(" + DEFAULT_SIDE_LENGTH + ")を使います。"); 10 } catch (NumberFormatException nfe) { 11 System.err.println("整数に変換できない値が入力されました。"); 12 System.exit(1); 13 } 14 scan.close();
に変更したうえで、以下のimport文
lang
1import java.util.NoSuchElementException;
を追加すれば、期待している動作になると思います。
投稿2015/05/07 12:51
編集2015/05/07 12:52総合スコア9058
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
こんにちは。
実際にプログラムを書く前に以下のように整理してから実装しました。
- 一辺の長さを n とするとき、
- ひし形全体では (2×n-1)行のテキストになる。
- 横幅の長さ(=左右の頂点を結ぶ対角線上に、両端も含めて文字が何個並ぶか)も、(2×n-1)となる。
- そこで、上記の数を m とする。すなわち、m = 2×n - 1 とする。
- 解くべき問題は、行インデクス i (0以上、m-1以下)の行の文字列を構成する m 個の
文字のうち、どれをアスタリスク( * )にすれば良いか?ということである。
これを以下のように考える。
- アスタリスク にするべきインデクスは最大2箇所あり、一番上と一番下の頂点となる行では1箇所である。
- この最大2箇所の * とするべきインデクスを p1, p2 (p1≦p2)とする。
(例:n=5のときの上から3行目(i=2)なら、p1=2, p2=6) - まず、p1とp2には p1 + p2 = m -1 という関係がある。
- 行インデクス i のときのp1の値を、p1(i)とすると、ひし形の上半分については
p1(0) = n-1
p1(i+1) = p(i) - 1
という漸化式が成り立つ。
- iの値が k のとき、p1(k) =0 になるとする。そのときの行は、左右頂点を構成する行になる。
- この、左右頂点を構成する行の次の行以降は、iが 0以上、(k-1)以下で描画した、ひし形の上半分の行を逆に出力していけばよい。
上記を実装したものが以下です。
おそらく元のコードとは少しアプローチの違うものになっていると思います。
また、メインとなるループで、行インデクス i はコードとしては不要でした。
lang
1package question9524; 2 3import java.util.ArrayList; 4import java.util.List; 5 6public class RhombusN { 7 8 private static final int DEFAULT_SIDE_LENGTH = 5; //辺の長さのデフォルト値 9 private static final int MAX_SIDE_LENGTH = 128; // 辺の長さの最大値 10 11 private static final char DRAW_LINES_CHAR = '*'; //辺を描く文字 12 private static final char BACKGROUND_CHAR = ' '; //背景の文字 13 14 public static void main(String[] args) { 15 16 // 描画するひし形の一辺の長さを表す変数 n 17 int n = DEFAULT_SIDE_LENGTH; 18 19 // 引数のチェック 20 if (args.length > 0) { 21 try { 22 n = Integer.parseInt(args[0]); 23 } catch (NumberFormatException nfe) { 24 System.err.println( 25 "与えられた引数は整数に変換できません。"); 26 System.exit(1); 27 } 28 } 29 30 if ( n > MAX_SIDE_LENGTH ) { 31 System.err.println( 32 "与えられた引数が最大値(" + MAX_SIDE_LENGTH + ")を超えます。"); 33 System.exit(1); 34 } 35 36 // 何行のテキストになるかを表す変数 m 37 final int m = 2 * n -1; 38 39 // 1行目から、左右頂点を含む行のひとつ前までを保存しておくリスト 40 List<String> firstHalfLines = new ArrayList<String>(); 41 42 // 各行の文字列でアスタリスクにする位置のうち小さいほうの変数の初期値 43 int p1 = n-1; 44 while ( p1 >= 0 ) { 45 // アスタリスクにする、もう一方の位置 46 int p2 = m -1 - p1; 47 48 //長さがmで、p1とp2の位置がアスタリスク、他はスペースの文字列を作成 49 String line = makeLine(m, p1, p2, DRAW_LINES_CHAR, BACKGROUND_CHAR); 50 51 //作成した文字列を出力 52 System.out.println(line); 53 54 // p1 が0ではないとき、この行を前半行リストに追加 55 if (p1 > 0 ) 56 firstHalfLines.add(line); 57 58 // p1 をデクリメント 59 p1 --; 60 } 61 62 //前半行リストを逆順に出力 63 final int numLines = firstHalfLines.size(); 64 for (int i = numLines-1; i >= 0; -- i ) { 65 System.out.println(firstHalfLines.get(i)); 66 } 67 } 68 69 // 長さがlengthで、p1とp2の位置が文字a、他は文字bの文字列を作成 70 private static String makeLine(int length, int p1, int p2, char a, char b) { 71 StringBuilder sb = new StringBuilder(); 72 73 for ( int i=0; i < length; ++ i ) { 74 char c = (i == p1 || i == p2 ? a : b ); 75 sb.append(c); 76 } 77 78 return sb.toString(); 79 } 80 81}
適切にクラスパスを通して、たとえば、一辺が32のひし形であれば、
java question9524.RhombusN 32
のように、起動パラメータに 32 を指定して起動します。
辺の最大値を、128としているのは、あまり意味はないですが、ターミナルで
実行するときにそのぐらいが適当かなという数字です。
これは何かの課題か何かでしょうか?
だとすると、元のコードの
lang
1if( i + j == 6 || j - i == 4 || i - j == 4 || i + j == 14){
に出てくる数字を、与えられた一辺の長さ n から求める計算式を
作らせることが出題の主旨かもしれません。
そうは思いつつも、ここでは冒頭に整理したことをそのままトレースした
ような(つまり、なるべく脳に汗をかかないで済む)コードにしてみました。
以上、参考になれば幸いです。
投稿2015/05/07 12:06
編集2015/05/07 13:30総合スコア9058
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。