用Java格式化Pascal的三角形

时间:2014-08-27 17:01:25

标签: java

我最近一直在教自己Java,我制作了一段代码来制作Pascal的三角形。但是,我无法在三角形中正确打印出来。我无法弄清楚如何考虑多位数字。这是我到目前为止所做的:

public class Pas{
   public static void main(String[] args){
    pas(20);
}

public static void pas(int rows){

    for(int i = 0; i < rows; i++){
        String spaces = "";
        int counter = (rows + 30)/2 - i;
        for(int f = counter; f > 0; f --){
            spaces += " ";

        }

        System.out.print(spaces);
        for(int j = 0; j <= i; j++){
            System.out.print( ncr(i, j) + " ");
        }
        System.out.println();
    }
}

public static long ncr(int n, int r){
    return fact(n) / (fact(r) * fact(n - r));
}

public static long fact(int n){
    long ans = 1;
    for(int i = 2; i <= n; i++){
        ans *= i;
    }
    return ans;
}

请记住,我是一个完整的初学者,从未接受任何实际指导。我所知道的一切都来自互联网,并在Eclipse中乱七八糟。

5 个答案:

答案 0 :(得分:1)

所以你遇到的问题是间距。

你在数字之后总是使用一个空格,这是一个问题,因为一个数字的长度可以是1 - 即:1,2,3,4,5,6,7,8,9 - 而另一个可以是长度为5 - 即31824.因此,您的三角形在右侧较宽。 要改变这一点,你必须为你的所有数字保留相等的空间 - 所以如果你的最大数字是184756,那么对于你打印的每个数字,你必须预留6位数字和1位空格。

此外,您的初始间距与行数无关,这通常会产生问题(如果您想使三角形大于30 - 您的当前常量)。

所以有两个地方我建议改变: 首先是(1)

int counter = (rows + 30)/2 - i; 

这里30是一个适用于你的20维三角形的常数,但它不优雅,不适用于更大的三角形。所以我建议像这样(2)

int counter = (maxNumberLength*(numberOfRows - i))/2; 

maxNumberLength是三角形中数字的最大长度。怎么计算呢?我估计像(3)

Math.pow(2d, numberOfRows.doubleValue()); 

此功率将始终大于三角形中的最大值,但不会太大。你可以用不同的方式做到这一点 - 这是我第一次想到的。

回到(2)... numberOfRows是三角形中的行数。在乘以前减去i以使每行中的初始空间maximumNumberLength/2变小(使其具有左斜率)。

我建议改变的第二件事是:

System.out.print( ncr(i, j) + " ");

这是最重要的部分,因为你总是添加1个空格。如果最大数字长度为6,那么您应该在1之后添加6个空格,在20之后添加5个空格,依此类推。这就是为什么我建议创建一个方法,它会返回你需要的空格数(4)

private String spaces(final Long number, final int maxNumberLength)
{
    StringBuilder spaces = new StringBuilder("");
    for (int i = 0; i<maxNumberLength - number.toString().length(); i++)
    {
        spaces.append(" ");
    }
    return spaces.toString();
}

(4)中,您将数字作为第一个参数(即空格后面的数字)和(3)中的maxNumberLength。这样,所有数字都会在输出中占用相同数量的空格。我使用StringBuilder构建空间,这对字符串连接更有效。

这就是它 - 两个变化,它应该工作。 我附上我的完整代码,如果您需要,可以测试它:

public class TraingleTest 
{
    private final BufferedReader input;
    private Integer numberOfRows;

    public static void main(String args[])
    {
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        new TraingleTest(input).run();
    }

    private TraingleTest(final BufferedReader input)
    {
        this.input = input;
    }

    private void run()
    {
        boolean validNumber = false;

        System.out.print("Please enter number of rows for Pascals Triangle: ");
        do
        {
            String usersInput = readUserInput();
            validNumber = validateInput(usersInput);
        } while (!validNumber);

        makeTriangle();
    }

    private String readUserInput()
    {
        try
        {
            return input.readLine();
        }
        catch (final IOException e)
        {
            System.out.print("Error while reading input. Please try one more time: ");
            return "";
        }
    }

    private boolean validateInput(final String input)
    {
        try
        {
            Integer inputValue = Integer.parseInt(input);
            if (inputValue > 2 && inputValue < 22)
            {
                numberOfRows = inputValue;
                return true;
            }

            System.out.print("Value must be an integer between 3 and 21. Please insert valid number: ");
            return false;
        }
        catch (final Exception e)
        {
            System.out.print("Error while parsing input. Please insert valid number: ");
        }
        return false;
    }

    private void makeTriangle()
    {
        int maxNumberLength = Double.valueOf(Math.pow(2d, numberOfRows.doubleValue())).toString().length();

        for(int i = 0; i < numberOfRows; i++){
            String spaces = "";
            int counter = (maxNumberLength*(numberOfRows - i))/2;
            for(int f = counter; f > 0; f --)
            {
                spaces += " ";
            }

            System.out.print(spaces);
            for(int j = 0; j <= i; j++)
            {
                long number = ncr(i, j);
                System.out.print(number + spaces(number, maxNumberLength));
            }
            System.out.println();
        }
    }

    private String spaces(final Long number, final int maxNumberLength)
    {
        StringBuilder spaces = new StringBuilder("");
        for (int i = 0; i<maxNumberLength - number.toString().length(); i++)
        {
            spaces.append(" ");
        }
        return spaces.toString();
    }

    public long ncr(int n, int r)
    {
        return fact(n) / (fact(r) * fact(n - r));
    }

    public long fact(int n)
    {
        long ans = 1;
        for(int i = 2; i <= n; i++)
        {
            ans *= i;
        }
        return ans;
    }
}

答案 1 :(得分:1)

//我没有输入你只能给出一个输入语句并输入no行

的行
public class PascalTriangle {
    public static void main(String[] args) {
        int rows = 10;
        for(int i = 0; i < rows; i++) {
            int number = 1;
            System.out.format("%"+(rows-i)*2+"s","");
            for(int j = 0; j <= i; j++) {
                 System.out.format("%4d",number);
                 number = number * (i - j) / (j + 1);
            }
            System.out.println();
        }
    }
}

答案 2 :(得分:0)

此代码可以帮助您

int rows = 10;


for(int i =0;i<rows;i++) {
    int number = 1;
    System.out.format("%"+(rows-i)*2+"s","");
    for(int j=0;j<=i;j++) {
         System.out.format("%4d",number);
         number = number * (i - j) / (j + 1);

    }
    System.out.println();
}

答案 3 :(得分:0)

最简单的方法是判断您输出的每个数字都将使用一定数量的字符,并在输出每个数字时根据需要添加额外的空格。例如,您可以决定每个数字将占用4个字符(如果所有数字都是9999或更少 - 实际上,Pascal的三角形有20行,您需要至少5个字符)。然后,您需要调整在三角形的每一行中打印出的空格数。

要将数字转换为4个字符的字符串,其中数字被推到4个字符&#34;框的右侧&#34;,如果需要,在左侧添加空格,请使用{{1 }}:

String.format

如果您希望号码位于&#34;框&#34;,

的左侧
String output = String.format("%4d", number);

如果您想要将数字置于&#34;框&#34;中心,则更难。这是一个用空格填充两边的字符串的方法,使填充尽可能接近相等:

String output = String.format("%-4d", number);

然后你可以说

public static String center(int desiredLength, String input) {
    if (input.length() >= desiredLength) {
        return input;
    }
    int leftPadding = (desiredLength - input.length()) / 2;
    int rightPadding = desiredLength - input.length() - leftPadding;
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < leftPadding; i++) {
         result.append(' ');
    }
    result.append(input);
    for (int i = 0; i < rightPadding; i++) {
         result.append(' ');
    }
    return result.toString();
}

或,如果System.out.print(center(4, Integer.toString(number))); number

long

(PS而不是System.out.print(center(4, Long.toString(number))); ,您可以将StringBuilder声明为result并使用String之类的内容,就像您在原始问题中所做的那样。同样,除了慢几纳秒之外。)

答案 4 :(得分:-1)

package myjavapractice;
import java.util.Arrays;
import java.util.Scanner;
public class pascaltriangle 
{
    public static void main(String args[]) {
    int i;
Scanner sc=new Scanner(System.in);
    int n=sc.nextInt();
    int[][] pascal=new int[n][];
    for(i=0;i<n;i++)
    {
        pascal[i]=new int[i+1];
    }
    pascal[0][0]=pascal[1][0]=pascal[1][1]=1;
    for(int j=2;j<n;j++) {
        pascal[j]=getNextRow(pascal[j]);
    }
    //print
    for(int k=0;k<n;k++)
    {
        System.out.println(Arrays.toString(pascal[k]));
    }
}


static int[] getNextRow(int[] p)
    {
        int[] current = new int[p.length];//row
        System.out.println("length "+p.length);
        current[0]=current[current.length-1]=1;//colmn

        for(int m=1;m<current.length-1;m++)
        {
        current[m]=p[m]+p[m-1]; 
        System.out.println("pof m is"+p[m]);
        }``
        return current;
    }
}