3

印刷する必要のある星のパターン 問題は、Nとして与えられた最大の正方形の辺から始めて、同心で入れ子になった正方形を作成することです。これは、紙に1つの正方形を描くのと同じように、辺の長さを4減らして、正方形を描くことができなくなるまで続けます。各正方形の後(サイドのstartPosから2つ、endPosから2つ); そして、Nは最初の正方形のサイズです。乗算記号('*')を使用して辺を描画する必要があります。

上の画像の比率(正方形よりも長方形のように見えます)は正確ではないかもしれませんが、何をする必要があるかについてのアイデアが得られます..以下のコードは私が試したものです...これは、印刷する必要がある正確なパターンです。

public static void main(String[] args)
{
    int N=9;
    int iLo=0;
    int iHi=N-1;
    int jLo=0;
    int jHi=N-1;

    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(i==0 || (i==N-1) || (j==0) || (j==N-1))
                System.out.print('*');
            else
            {
                if(i<=N/2)
                {
                    if((i%2==0) && (i>=iLo) && (i<=iHi) && (j>=jLo) && (j<=jHi))
                        System.out.print('*');
                    else
                        if(i==iLo || i==iHi )
                            System.out.print('*');
                        else
                            System.out.print(' ');  
                }
                else
                {
                    if((i%2==0) && (i>=iLo) && (i<=iHi) && (j>=jLo) && (j<=jHi))
                            System.out.print('*');
                        else
                            System.out.print(' ');  
                }

            }

        }
        System.out.print("  i-->"+i+"   iLo-->"+iLo+" iHi-->"+iHi+" jLo-->"+jLo+" jHi-->"+jHi);
        if(i%2>0)
        {
            if(i<=N/2)
            {
                jLo=jLo+2;
                jHi=jHi-2;
                iLo=iLo+1;
                iHi=iHi-1;
            }
            else
            {
                jLo=jLo-2;
                jHi=jHi+2;
                iLo=iLo-1;
                iHi=iHi+1;
            }
        }
        else
        {

        }

        System.out.println();
    }

}
4

3 に答える 3

1

これは、毎回2ずつ減少するforループ(i-= 2)を使用するか、ベースケースが画面に単一の*を出力するか、まったく出力しない場合に再帰的に解決できます。他の人が投稿したように、各正方形の間にスペースがない限り、塗りつぶされた正方形しかありません。

編集:ある正方形を別の正方形の上に印刷するのではなく、別の正方形の代わりに印刷しているようです。ただし、同じ戦略が適用されます。

EDIT2:iとjでネストされたforループを使用する必要はありません。変数iとして各辺の長さを持つ単一のforループで十分です。ただし、頂点の二重カウントを調整する必要があります。

次のようなものを試してみませんか:

// Assumes a cartesian coordinate system, origin at bottom left.
int startingX = 0;
int startingY = 0;
while( length > 0 ){
  printHorizontally(length, startingX, startingY);
  printVertically(length, startingX, startingY);
  startingX += 2;
  startingY += 2;
  length -= 4; 
}

private void printHorizontally(int length, int startingX, int startingY){
  // Prints length *s to the screen in a horizontal line starting at the
  // given points.  Define printVertically similarly.    
}
于 2012-06-15T19:28:40.863 に答える
0

概要

この質問は、本質的にレンダリングアルゴリズムであるため、Adobeに適しています。ピクセルと一連のルールを指定して、そのピクセルの外観を計算します。

これを行う最も効率的な方法は、「サイズnの正方形の位置(x、y)を指定し、それを?でマークする必要がある」と答えるテストを考え出し、*各位置についてその質問に答えることです。

最初にいくつかの観察を行うことで、この質問に答えることができます。

  • このアルゴリズムの出力の対称性に注意してください。対角線に沿って正方形を切り取ると、4つの三角形の象限が残ります。各象限内で、三角形が単純に縞模様になっていることに注意してください。
  • 縦または横のストライプは簡単に描画できます。行/列が最も近いエッジから等距離にあるかどうかを確認し、等距離にある場合はシェーディングします。

したがって、位置ごとに2つの計算を実行します。(1)どの象限がこの位置にあるか、(2)この象限が与えられた場合、この位置の行/列をシェーディングする必要がありますか?

実装例(python)

def getQuadrant(i,j,n):
    # 1 means top quadrant; 2 right; 3 bottom; 4 left
    half_n = float(n-1)/2
    x = float(i) - half_n
    y = float(j) - half_n
    if x > 0:
        if y > 0:
            if x > y:
                return 3
            else:
                return 2
        else:
            if x > -1*y:
                return 3
            else:
                return 4
    else:
        if y > 0:
            if -1*x > y:
                return 1
            else:
                return 2
        else:
            if x < y:
                return 1
            else:
                return 4

def isPixelShaded(x,y,n):
    q = getQuadrant(x,y,n)
    if q == 1:
        return (x % 2) == 0
    elif q == 2:
        return ((n-y-1) % 2) == 0
    elif q == 3:
        return ((n-x-1) % 2) == 0
    else:
        return (y % 2) == 0

def getPixelShade(x,y,n):
    if isPixelShaded(x,y,n):
        return ' * '
    else: 
        return '   '

def printSquare(n):
    for i in range(n):
        print ''.join(map(lambda x: str(getPixelShade(i,x,n)),range(n)))

printSquare(3)
printSquare(6)
printSquare(9)

出力

 *  *  * 
 *     * 
 *  *  * 
 *  *  *  *  *  * 
 *              * 
 *     *  *     * 
 *     *  *     * 
 *              * 
 *  *  *  *  *  * 
 *  *  *  *  *  *  *  *  * 
 *                       * 
 *     *  *  *  *  *     * 
 *     *           *     * 
 *     *     *     *     * 
 *     *           *     * 
 *     *  *  *  *  *     * 
 *                       * 
 *  *  *  *  *  *  *  *  * 

他の考え

ここで採用したレンダリングアプローチの代わりに、事前に割り当てられたマトリックスで「正方形をウォークアウト」することで反復アプローチを採用することもできます。このアプローチは考えるのが簡単ですが、より多くのメモリを必要とします。さらに、この回答で説明されているアプローチには、特定の位置が影付きであるかどうかを判断するために、隣接する位置について知る必要がないという利点があります(反復アプローチではそうなります)。これは、最終レンダリングの小さな見本を一度にレンダリングできることを意味します。言い換えれば、このアプローチは並列処理をサポートします。これは常に素晴らしいボーナスです。

于 2012-06-15T21:47:32.170 に答える
0

次のコードは、可能な限り最も単純な再帰的ソリューションを提供します---

パブリッククラスSquaresInSquare{

private static char[][] arr;


public static void populate(int start,int N)
{
    //System.out.println(start+" "+N);
    if(N < 0 || start > N)
        return;

    for (int i = start; i < N; i++)
    {
        for (int j = start; j < N; j++)
        {
            if(i==start || i==N-1 || j==start || j==N-1)
                arr[i][j]='*';
            else
                arr[i][j]=' ';
        }
    }

    populate(start+2,N-2);
}

public static void print()
{
    for (int i = 0; i < arr.length; i++)
    {
        for (int j = 0; j < arr.length; j++)
        {
            System.out.print(arr[i][j]);
        }
        System.out.println();
    }
}

/**
 * @Method :main is Personal Method Of Class-->SquaresInSquare
 * @returns : void
 * @param args
 */
public static void main(String[] args)
{
    int N=21;
    arr=new char[N][N];
    populate(0,N);
    print();

}

}

于 2012-06-29T09:47:53.080 に答える