Java - 如何将两个类似的for循环组合成一个循环

时间:2016-05-17 15:57:37

标签: java loops for-loop

我有两个类似的循环,我被要求消除其中一个,但我不知道如何...

这是我的代码:

import java.util.Scanner;


public class Tree {

public static void main(String[] args) {

    Scanner input = new Scanner(System.in);

    System.out.print("Enter height: ");
    int tmp = input.nextInt();

    int x = (tmp-1)*2+1;
    int y = x/2;
    int z = 1;

    for(int i=0; i<tmp; i++){

        for(int j=0; j<=y; j++){
            System.out.print(" ");
        }
        for(int k=0; k<z; k++){
            System.out.print("*");
        }
        System.out.println();
        y--;
        z+=2;
    }
    for(int i=0; i<tmp; i++){
        y++;
        for(int j=0; j<=y; j++){
            System.out.print(" ");
        }

        z-=2;
        for(int k=0; k<z; k++){
            System.out.print("*");
        }

        System.out.println();

    }

}

}

我应该编写一个方法并调用它吗?

我挣扎了好几天..

希望得到一个简单的建议,因为我只是一名初学者。

非常感谢您的帮助。谢谢!

4 个答案:

答案 0 :(得分:1)

我认为应该在更高层次上考虑问题:

您想拥有的内容(基于您的代码)是代表钻石的*的二维矩阵,因此让我们尝试使用两个for循环的解决方案,对应于矩阵/屏幕的两个维度,有一些条件来定义每个&#34;像素的渲染&#34;:

// vertical dimension (i:= line index)
for (int i =0; i< 2* tmp +1 ; ++i){
        if(i!=tmp){ //handling of middle-line corner case

            // horizontal dimension (j:= row index)
            for (int j=0; j< 2*tmp ; ++j){
                if (condition(tmp, i,j)){
                    System.out.print("*");
                }else{
                    System.out.print(" ");
                }
            }

            if(i!=2 * tmp) { // handling of last line corner case
                System.out.println();
            }
        }
    }

    private boolean condition(int tmp, int i, int j) {

        // return true if and only if the (i, j) pixel is within the central diamond
        return Math.abs(tmp-i) + Math.abs(tmp-j) <= tmp;        
    }

角落情况的两种处理只是为了匹配你的结果。

答案 1 :(得分:0)

首先考虑删除此循环:

for(int k=0; k<z; k++){
System.out.print("*");
}

删除此运行前一个循环结束,这意味着运行上一个循环到y + z,然后将一个if条件打印到*或空格。

答案 2 :(得分:0)

最简单的清理工作包括通过函数引入抽象:

Scanner input = new Scanner(System.in);

System.out.print("Enter height: ");
int height = input.nextInt();

int x = (height-1)*2+1;
int y = x/2;
int z = 1;

for (int i = 0; i < height; i++) {
    printRepeated(y, " ");
    printRepeated(z, "*");
    System.out.println();
    y--;
    z += 2;
}
for (int i = 0; i < height; i++) {
    y++;
    z -= 2;
    printRepeated(y, " ");
    printRepeated(z, "*");
    System.out.println();
}

带有帮助功能:

private void printRepeated(int repetitions, String s) {
    System.out.print(String.format("%" + repetitions + "s", "").replace(" ", s));
}

如果您根据yz表达xi,则可能会合并循环。 对于第二个循环for (i = height; i < x; ++i)。我把它留作谜题。

答案 3 :(得分:0)

有趣的问题!

考虑在屏幕上打印此钻石的一种方法是查看空格的打印次数以及2*h行中每个h行打印的星号数量1, 2, ..., n 。所以,你肯定需要两个循环(一个在另一个内) - 一个用于计算行数,另一个用于计算每行的内容。但是你可以避免重复你的程序所做的那两个循环。一个技巧是选择外部循环的索引范围,这样虽然该索引遵循单调序列(例如1, 2, ..., k, k, k-1, k-2, ..., 1)而内部循环索引遵循交替序列(例如Math.abs)。

可能有几种方法可以做到这一点,但以下似乎可以很好地完成这项工作。它需要public static void printDiamond(int h) { int ns; // number of spaces int na; // number of asterisks for (int i = -h; i < h; i++) { ns = i == 0 ? 1 : (i < 0 ? Math.abs(i) : i + 1); na = i == 0 ? (2*h - 1) : (i < 0 ? (2 * h) - (2 * Math.abs(i)) + 1 : (2 * h) - (2 * i) - 1); for (int j = 1; j <= ns; j++) { System.out.print(" "); } for (int k = 1; k <= na; k++) { System.out.print("*"); } System.out.println(); } } 函数的帮助:

Enter height: 5
     *
    ***
   *****
  *******
 *********
 *********
  *******
   *****
    ***
     *

它产生的输出与程序的输出相同:

use strict