【问题标题】:How do I simplify these For-loops to save lines of code? [closed]如何简化这些 For 循环以节省代码行? [关闭]
【发布时间】:2014-12-21 06:44:38
【问题描述】:

代码的输出显示如下:

下面的代码对我来说似乎很时髦,即使是新手。我想代码可以更有效地完成,或者至少可以节省几行代码,而不必抽出这么多循环。

如果有人可以提供更清洁的解决方案,请提前致谢。

public class diamond    {
    public static void main(String[] args) {
        for (int c=1; c<=10; c++) {
            for (int d=1; d<=11-c; d++) {
                System.out.print("*");
            }
            for (int e=2; e<c*2; e++) {
                System.out.print(" ");
            }
            for (int i=1; i<=11-c; i++) {
                System.out.print("*");
            }
            System.out.println();
        }
        for (int f=2; f<=10; f++) {
            for (int g=1; g<=f; g++) {
                System.out.print("*");
            }
            for (int h=2; h<22-f*2; h++) {
                System.out.print(" ");
            }
            for (int j=1; j<=f; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

【问题讨论】:

  • 我立即了解您的代码在做什么的事实是最大的迹象表明它的方式非常好。在专业开发中,清晰易读的代码远比缩短几行代码或微优化代码以节省几个 CPU 周期更有价值。
  • @VGR 我不能同意这是“清晰易读的代码”。也许您发现了这一点,因为您已经非常准确地知道它要达到的目标。我认为大多数对正在解决的问题一无所知的人不会仅仅通过阅读它就能“立即”理解该代码在做什么。即使在知道要解决的问题之后,下面发布的大多数答案也更容易理解。

标签: java loops for-loop while-loop simplify


【解决方案1】:

关键是要注意代码中的重复模式并将其排除在外。

您可以使用辅助方法打印一系列 N 个字符:

public static void printNTimes(char value, int n) {
    for (int i = 0; i < n; i++) {
        System.out.print(value);
    }
}

您可以通过对所涉及的字符和菱形大小使用常量来概括该方法。

private static final char OuterChar = '*';
private static final char InnerChar = ' ';
private static final int Size = 10;

并添加另一个辅助方法来打印一行,其中 N 个字符的实例在外部,2 * (Size - N) 字符在内部:

private static void printRow(int n) {
    printNTimes(OuterChar, n);
    printNTimes(InnerChar, (Size - n) * 2);
    printNTimes(OuterChar, n);
    System.out.println();
}

然后你的代码变成:

public class diamond
{
    private static final char OuterChar = '*';
    private static final char InnerChar = ' ';
    private static final int Size = 10;

    public static void printNTimes(char value, int n) {
        for (int i = 0; i < n; i++) {
            System.out.print(value);
        }
    }

    private static void printRow(int n) {
        printNTimes(OuterChar, n);
        printNTimes(InnerChar, (Size - n) * 2);
        printNTimes(OuterChar, n);
        System.out.println();
    }

    public static void main(String[] args) {
        for (int c = Size; c >= 1; c--) {
            printRow(c);
        }
        for (int c = 2; c <= Size; c++) {
            printRow(c);
        }
    }
}

【讨论】:

  • 对 OOP 设计的赞誉。不过,我会改变在方法调用中使用硬编码字符串。
  • @CreationEdge 我不认为我在原始答案中使用了 OOP 设计,但感谢您的称赞。 :) 我已经修改了我的答案,以考虑您的建议并进行更多重构。
  • 鉴于这是一个 Java 问题,您的“const”声明将无法编译。我假设您的意思是“静态”,对吧?
  • @skomi 看起来我的意思是static final。我已经有一段时间没有使用 Java 了。
【解决方案2】:
int max=9,min=10;
        for(int i=0;i<19;i++){
            for(int j=0;j<20;j++){

                if(j<min || j>max){
                    System.out.print("*");
                }
                else{
                    System.out.print(" ");
                }
            }
            if(i<9){
                min--;
                max++;
            }
            else {
                min++;
                max--;
            }
            System.out.println();
        }

【讨论】:

    【解决方案3】:

    我觉得这很清楚,但是 YMMV。

    for( int i = 10; i >= 1; i-- ){
        String s = "**********".substring(0, i);
        System.out.printf( "%-10s%10s\n", s, s );
    }
    for( int i = 1; i <= 10; i++ ){
        String s = "**********".substring(0, i);
        System.out.printf( "%-10s%10s\n", s, s );
    }
    

    【讨论】:

      【解决方案4】:

      因为这是在循环中重复的:

        for (int d=1; d<=11-c; d++)
           {
              System.out.print("*");
           }
      

      您可以将其写入变量并打印两次。这将消除两个循环。 (每个外循环一个子循环)

      【讨论】:

        【解决方案5】:

        我喜欢将逻辑封装在易于阅读和维护的代码中,因此我编写了一个带有描述性方法的类,而不是执行大量嵌套的 for 循环。

        package se.wederbrand.stackoverflow.diamond;
        
        import java.util.ArrayList;
        import java.util.List;
        
        public class Diamond {
            final List<String> rows;
        
        
            public static void main(String[] args) {
                System.out.println(new Diamond(10));
            }
        
            public Diamond(int width) {
                this.rows = new ArrayList<>();
                for (int stars = 1; stars <= width; stars++) {
                    // add all rows, start from the middle and build around it
                    addRows(stars, width);
                }
            }
        
            private void addRows(int stars, int width) {
                String row = generateRow(stars, width);
                // add on top
                this.rows.add(0, row);
                if (stars > 1) {
                    // add to bottom
                    this.rows.add(row);
                }
            }
        
            private String generateRow(int stars, int width) {
                String row = "";
                int spaces = width - stars;
                for (int j = 0; j < stars; j++) {
                    row += "*";
                }
                for (int j = 0; j < spaces; j++) {
                    row += "  ";
                }
                for (int j = 0; j < stars; j++) {
                    row += "*";
                }
                return row;
            }
        
            @Override
            public String toString() {
                String diamond = "";
                for (String row : rows) {
                    diamond += row + System.lineSeparator();
                }
                return diamond;
            }
        }
        

        【讨论】:

          【解决方案6】:

          这是一个有趣的问题,因为您可以看到每个人如何采用不同的方法来解决它。这种方式只会给你一个在另一边用另一个字符“填充”的字符串。

          public static void main(String[] args) {
              for (int c = 1; c <= 10; c++) {
                  System.out.println(printPadded(11 - c, '*',  (c - 1) * 2, ' '));
              }
              for (int f = 10; f >= 2; f--) {
                  System.out.println(printPadded(11 - f, '*',  (f - 1) * 2, ' '));
              }
          }
          
          public static String printPadded(int padCount, char padCharacter, 
                    int middleCount, char middleCharacter) {
              StringBuilder s = new StringBuilder(padCount * 2 + middleCount);
              for (int i = 0; i < padCount; i++) {
                  s.append(padCharacter);
              }
              for (int i = 0; i < middleCount; i++) {
                  s.append(middleCharacter);
              }
              for (int i = 0; i < padCount; i++) {
                  s.append(padCharacter);
              }
              return s.toString();
          }
          

          【讨论】:

            猜你喜欢
            • 2013-12-08
            • 1970-01-01
            • 2020-07-06
            • 1970-01-01
            • 2021-02-26
            • 1970-01-01
            • 2020-02-18
            • 1970-01-01
            • 2014-01-12
            相关资源
            最近更新 更多