質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

javaの繰り返しに関する問題です

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,877
退会済みユーザー

退会済みユーザー

java初心者です。
forの繰り返しについての質問です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

回答 6

checkベストアンサー

0

再び、こんにちは。

質問にある、辺の長さ5の場合のコードの
if( i + j == 6 || j - i == 4 || i - j == 4 || i + j == 14){ 
は、辺の長さが n のときは
if( i + j == n+1 || j - i == n-1 || i - j == n-1 || i + j == 3*n-1 ){ 
でした。なので、元のコードに出てくる具体的な数値(10,6,4,14)を入力された値で
置き換えたバージョンは、以下で良さそうです。
package question9524;

import java.util.Scanner; 

public class RhombusN2 { 
    public static void main(String args[]) { 

         System.out.print("一辺の長さを入力して下さい。:");

         Scanner scan = new Scanner(System.in);
         int n = scan.nextInt();
         scan.close();
        
        //縦 
        for(int i = 1; i < 2*n; i++){ 
            //横 
            for(int j = 1; j < 2*n; j++){ 
                //条件 
                if( i + j == n+1 || j - i == n-1 || i - j == n-1 || i + j == 3*n-1 ){ 
                    System.out.print("*"); 
                } else { 
                    System.out.print(" "); 
                } 
            } 
            System.out.print("\n"); 
        } 
    } 
} 

自分もテストしてみました。
MGX82JA:bin ykt68$ java question9524.RhombusN2
一辺の長さを入力して下さい。:1
*
MGX82JA:bin ykt68$ java question9524.RhombusN2
一辺の長さを入力して下さい。:5
    *    
   * *   
  *   *  
 *     * 
*       *
 *     * 
  *   *  
   * *   
    *    
MGX82JA:bin ykt68$ java question9524.RhombusN2
一辺の長さを入力して下さい。:12
           *           
          * *          
         *   *         
        *     *        
       *       *       
      *         *      
     *           *     
    *             *    
   *               *   
  *                 *  
 *                   * 
*                     *
 *                   * 
  *                 *  
   *               *   
    *             *    
     *           *     
      *         *      
       *       *       
        *     *        
         *   *         
          * *          
           *           
MGX82JA:bin ykt68$ 

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/05/09 12:34

    皆さん回答ありがとうございます。理解できました。

    キャンセル

0

こんにちは。
実際にプログラムを書く前に以下のように整理してから実装しました。

1. 一辺の長さを n とするとき、
  • ひし形全体では (2×n-1)行のテキストになる。
  • 横幅の長さ(=左右の頂点を結ぶ対角線上に、両端も含めて文字が何個並ぶか)も、(2×n-1)となる。
  • そこで、上記の数を m とする。すなわち、m = 2×n - 1 とする。

2. 解くべき問題は、行インデクス 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 はコードとしては不要でした。

package question9524;

import java.util.ArrayList;
import java.util.List;

public class RhombusN {

    private static final int DEFAULT_SIDE_LENGTH = 5;    //辺の長さのデフォルト値
    private static final int MAX_SIDE_LENGTH = 128;        // 辺の長さの最大値
    
    private static final char DRAW_LINES_CHAR = '*';        //辺を描く文字
    private static final char BACKGROUND_CHAR = ' ';        //背景の文字
    
    public static void main(String[] args) {

        // 描画するひし形の一辺の長さを表す変数 n
        int n = DEFAULT_SIDE_LENGTH;

        // 引数のチェック
        if (args.length > 0) {
            try {
                n = Integer.parseInt(args[0]);
            } catch (NumberFormatException nfe) {
                System.err.println(
                   "与えられた引数は整数に変換できません。");
                System.exit(1);
            }
        }
        
        if ( n > MAX_SIDE_LENGTH ) {
            System.err.println(
                  "与えられた引数が最大値(" + MAX_SIDE_LENGTH + ")を超えます。");
            System.exit(1);
        }
        
        // 何行のテキストになるかを表す変数 m 
        final int m = 2 * n -1;
        
        // 1行目から、左右頂点を含む行のひとつ前までを保存しておくリスト
        List<String> firstHalfLines = new ArrayList<String>();
        
        // 各行の文字列でアスタリスクにする位置のうち小さいほうの変数の初期値
        int p1 = n-1;
        while ( p1 >= 0 ) {
            // アスタリスクにする、もう一方の位置
            int p2 = m -1 - p1;
            
            //長さがmで、p1とp2の位置がアスタリスク、他はスペースの文字列を作成
            String line = makeLine(m, p1, p2, DRAW_LINES_CHAR, BACKGROUND_CHAR);
            
            //作成した文字列を出力
            System.out.println(line);
            
            // p1 が0ではないとき、この行を前半行リストに追加
            if (p1 > 0 )
                firstHalfLines.add(line);
            
            // p1 をデクリメント
            p1 --;
        }
        
        //前半行リストを逆順に出力
        final int numLines = firstHalfLines.size();
        for (int i = numLines-1; i >= 0;  -- i ) {
            System.out.println(firstHalfLines.get(i));
        }
    }
    
    // 長さがlengthで、p1とp2の位置が文字a、他は文字bの文字列を作成
    private static String makeLine(int length, int p1, int p2, char a, char b) {
        StringBuilder sb = new StringBuilder();
        
        for ( int i=0; i < length; ++ i ) {
            char c = (i == p1 || i == p2 ? a : b );
            sb.append(c);
        }
        
        return sb.toString();
    }

}
適切にクラスパスを通して、たとえば、一辺が32のひし形であれば、
java question9524.RhombusN 32
のように、起動パラメータに 32 を指定して起動します。
辺の最大値を、128としているのは、あまり意味はないですが、ターミナルで
実行するときにそのぐらいが適当かなという数字です。

これは何かの課題か何かでしょうか?
だとすると、元のコードの
if( i + j == 6 || j - i == 4 || i - j == 4 || i + j == 14){ 
に出てくる数字を、与えられた一辺の長さ n から求める計算式を
作らせることが出題の主旨かもしれません。
そうは思いつつも、ここでは冒頭に整理したことをそのままトレースした
ような(つまり、なるべく脳に汗をかかないで済む)コードにしてみました。

以上、参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/05/07 21:16

    こんにちは。見落としていたのですが、辺の長さは、標準入力から指定するのですね。上記のコードでは起動パラメータ args[0] で受け取っています。すみません。ご了承ください。

    キャンセル

0

再び、こんにちは。

Scanner を使って標準入力から辺の長さを指定する場合、
先に挙げたコードで、args[0]から n を求めている以下の部分:
        // 引数のチェック
        if (args.length > 0) {
            try {
                n = Integer.parseInt(args[0]);
            } catch (NumberFormatException nfe) {
                System.err.println("与えられた引数は整数に変換できません。");
                System.exit(1);
            }
        }
を、以下
        // Scannerから一辺の長さを取得する
        System.out.print("一辺の長さを入力して下さい。:");

        Scanner scan = new Scanner(System.in);
        try {
            n = Integer.parseInt(scan.next());
        } catch (NoSuchElementException nsee) {
            System.out.println("\r辺の指定がなかったので、" 
                + "デフォルト値(" + DEFAULT_SIDE_LENGTH  + ")を使います。");
        } catch (NumberFormatException nfe) {
            System.err.println("整数に変換できない値が入力されました。");
            System.exit(1);
        }
        scan.close();
に変更したうえで、以下のimport文
import java.util.NoSuchElementException;
を追加すれば、期待している動作になると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/05/07 21:55

    n = Integer.parseInt(scan.next());
    の代わりに
    n = scan.netInt();
    にすると,NumberFormatExceptionのcatch節が不要になります.

    キャンセル

  • 2015/05/07 21:56

    ×netInt → ○nextInt

    キャンセル

  • 2015/05/07 22:02

    swordoneさん、こんにちは。ありがとうございます。実はScannerを使ったコード、この回答で初めてでした!便利ですね。(Tiger以降で登場したものには、けっこう疎いです。)

    キャンセル

0

import java.util.Scanner;

public class Rhombus{
    public static void main(String args[]) {

    System.out.println("整数を入力してください。");
    Scanner in = new Scanner(System.in);
    int x = in.nextInt();

    for (int i = 0; i < x * 2 - 1; i++) {
        for (int j = 0; j < x * 2 - 1; j++) {
        System.out.print(cond(x, i, j));
        }
        System.out.print("\n");
    }
    }
    static String cond(int len, int x, int y) {
    int lenx = len - 1;
    if (Math.abs(x - lenx) + Math.abs(y - lenx) == lenx) {
        return "*";
    }
    return " ";
    }
}
実行例:
$ java Rhombus
整数を入力してください。
1
*
$ java Rhombus
整数を入力してください。
2
 * 
* *
 * 
$ java Rhombus
整数を入力してください。
3
  *  
 * * 
*   *
 * * 
  *  
$ java Rhombus
整数を入力してください。
4
   *   
  * *  
 *   * 
*     *
 *   * 
  * *  
   *   
平面上で 
x*x + y*y = r *2  は 中心が (0, 0), 半径 r の 円 (circle) を表します。
abx(x) + abas(y) = r は 中心が (0, 0), 一片の長さ r の四角を表します。

↑の java コードでは、中心を (r, r) にずらしてこの四角を描くという方法をとっています。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

では、私も一つ。
学校の課題っぽいですね。
楽しそうなので私もやってみました。
import java.util.Scanner;
import java.lang.Math;
public class Rhombus { 
    public static void main(String args[]) { 
        System.out.print("菱形の1辺の長さは?:"); 
        int x = 0;
        while(x == 0){
            Scanner scan = new Scanner(System.in);
            String str = scan.next();
            try {
                x = Integer.parseInt(str);
                break;
            } catch (NumberFormatException nfex) {
                System.out.print("整数を入力してね。:"); 
            }
        }
        int y = x - 1;
        int n = (x * 2) - 1;
        //縦 
        for(int i = 0; i < n; i++){ 
            //横 
            for(int j = 0; j < n; j++){ 
                //条件 
                if(Math.abs(i - j) == y || y - j == i || (y) * 2 - i + (y) == j){ 
                    System.out.print("*"); 
                } else { 
                    System.out.print(" "); 
                } 
            } 
            System.out.print("\n"); 
        } 
    } 
} 
C:\java>java Rhombus
菱形の1辺の長さは?:1
*

C:\java>java Rhombus
菱形の1辺の長さは?:2
 *
* *
 *

C:\java>java Rhombus
菱形の1辺の長さは?:3
  *
 * *
*   *
 * *
  *

C:\java>java Rhombus
菱形の1辺の長さは?:4
   *
  * *
 *   *
*     *
 *   *
  * *
   *

C:\java>java Rhombus
菱形の1辺の長さは?:5
    *
   * *
  *   *
 *     *
*       *
 *     *
  *   *
   * *
    *

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

この問題、面白いですね。

先の回答で挙げさせて頂きました
RhombusN2
を以下の2点を満たすように修正できないか考えました。

(1) for()のカッコの中と、アスタリスクにするときの if()のカッコの中だけを修正

(2) if()のカッコの中を、|| を使わない端的なものにする。

それで、以下ができました。

package question9524;

import java.util.Scanner; 

public class RhombusN3 { 
    public static void main(String args[]) { 

         System.out.print("一辺の長さを入力して下さい。:");

         Scanner scan = new Scanner(System.in);
         int n = scan.nextInt();
         scan.close();
                 
        //縦 
        for(int y = n-1; y >=  -(n-1) ; y -- ){ 
            //横 
            for(int x = -(n-1); x <= n-1; x ++ ){ 
                //条件 
                if( Math.abs(x) + Math.abs(y) == n-1  ){ 
                    System.out.print("*"); 
                } else { 
                    System.out.print(" "); 
                } 
            } 
            System.out.print("\n"); 
        } 
    } 
} 

MGX82JA:bin ykt68$ java question9524.RhombusN3
一辺の長さを入力して下さい。:1
*
MGX82JA:bin ykt68$ java question9524.RhombusN3
一辺の長さを入力して下さい。:5
    *    
   * *   
  *   *  
 *     * 
*       *
 *     * 
  *   *  
   * *   
    *    
MGX82JA:bin ykt68$ java question9524.RhombusN3
一辺の長さを入力して下さい。:12
           *           
          * *          
         *   *         
        *     *        
       *       *       
      *         *      
     *           *     
    *             *    
   *               *   
  *                 *  
 *                   * 
*                     *
 *                   * 
  *                 *  
   *               *   
    *             *    
     *           *     
      *         *      
       *       *       
        *     *        
         *   *         
          * *          
           *           
MGX82JA:bin ykt68$ 

ひし形の2本の対角線が直交する交点の座標を(0,0)としてXY座標を考えると、
アスタリスクにする座標(x,y)では、
Math.abs(x) + Math.abs(y) == n-1
が成り立ちます。

方眼紙か何かで描いてみると分かり易いです。
ちなみにターミナルで実行するとひし形に見えますが、
座標上に点を打つと考えると、出来上がるのは正方形
ですね。


投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る