Таким образом, проблема, с которой вы сталкиваетесь, - это расстояние.
Вы используете всегда одно место после номера, что является проблемой, потому что одно число может быть длиной 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 Dimention треугольника, но это не так элегантно и не будет работать для больших треугольников. Поэтому я хотел бы предложить что-то вроде этого (2):
int counter = (maxNumberLength*(numberOfRows - i))/2;
maxNumberLength
максимальная длина номера в вашем треугольнике может получить. Как рассчитать это? I'have оценивается как что (3):
Math.pow(2d, numberOfRows.doubleValue());
Эта сила всегда будет больше, чем самая большая ценность в треугольнике, но не намного. Вы можете сделать это по-другому - это первое, что пришло мне в голову.
Итак, вернемся к (2) ... numberOfRows - это количество строк в треугольнике. Вы вычитаете i
перед умножением, чтобы получить начальное пространство maximumNumberLength/2
меньше в каждой строке (так, чтобы он имел левый наклон).
Вторая вещь, которую я хотел бы предложить изменение заключается в следующем:
System.out.print(ncr(i, j) + " ");
Это самая важная часть, как вы всегда добавить 1 место. Если максимальная длина номера равна 6, вы должны добавить 6 пробелов после 1
, 5 пробелов после 20
и так далее. Вот почему я предлагаю создать метод, который будет возвращать вам количество пробелов, что вам нужно (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) вы берете номер в качестве первого PARAM (это число, которое должно быть затем пробелы) и maxNumberLength
от (3). Таким образом, все ваши номера будут занимать одинаковое количество пробелов на выходе. Я создаю пробелы с 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;
}
}
@Adi Он/она обеспокоен форматированием вывода консоли. –