Форматирование чисел с одинаковым количеством отступов
Я хочу отформатировать 3-значные поплавки на Java, чтобы они выстроились вертикально таким образом, чтобы они выглядели следующим образом:
123.45
99
23.2
45
Когда я использую класс DecimalFormat, я становлюсь близко, но я хочу вставить пробелы, когда элемент имеет 1 или 2 цифры.
Мой код:
DecimalFormat formatter = new java.text.DecimalFormat("####.##");
float [] floats = [123.45, 99.0, 23.2, 45.0];
for(int i=0; i<floats.length; i++)
{
float value = floats[i];
println(formatter.format(value));
}
Он производит:
123.45
99
23.2
45
Как я могу напечатать его так, чтобы все, кроме первой строки, были сдвинуты на 1 пробел?
Ответы
Ответ 1
Попробуйте с String.format()
(JavaDoc):
public static void main(String args[]){
String format = "%10.2f\n"; // width == 10 and 2 digits after the dot
float [] floats = {123.45f, 99.0f, 23.2f, 45.0f};
for(int i=0; i<floats.length; i++) {
float value = floats[i];
System.out.format(format, value);
}
а выход:
123.45
99.00
23.20
45.00
Ответ 2
Это тривиально с заменой строки регулярного выражения.
formatter.format(f).replaceAll("\\G0", " ")
Здесь он находится в контексте: (см. также на ideone.com):
DecimalFormat formatter = new java.text.DecimalFormat("0000.##");
float[] floats = {
123.45f, // 123.45
99.0f, // 99
23.2f, // 23.2
12.345f, // 12.35
.1234f, // .12
010.001f, // 10
};
for(float f : floats) {
String s = formatter.format(f).replaceAll("\\G0", " ");
System.out.println(s);
}
Это использует DecimalFormat
для большей части форматирования (нулевое дополнение, необязательный #
и т.д.), а затем использует String.replaceAll(String regex, String replacement)
заменить все ведущие нули на пробелы.
Образец регулярного выражения \G0
. То есть 0
, которому предшествует \G
, который является якорем "конца предыдущего совпадения". \G
также присутствует в начале строки, и это то, что позволяет привести нули (и никакие другие нули) к совпадению и заменить пробелами.
Ссылки
В escape-последовательности
Причина, по которой шаблон \G0
записывается как "\\G0"
как литерал строки Java, заключается в том, что обратная косая черта является символом escape. То есть, "\\"
- это строка длиной одна, содержащая обратную косую черту.
Ссылки
Связанные вопросы
Дополнительные советы
Обратите внимание, что я использовал цикл for-each
, что приводит к значительно более простому коду, что повышает читаемость и минимизирует вероятность ошибок. Я также сохранил переменные с плавающей запятой как float
, используя суффикс f
, чтобы объявить их как float
литералы (поскольку они по умолчанию double
), но нужно сказать, что в целом вы должен предпочесть double
в float
.
См. также
Ответ 3
Просто измените свою первую строку, заменив символы "#" на "0" . Он решит вашу проблему и создаст форматированные числа с одинаковой длиной, как описано в Java API. С помощью этого метода ваши строки будут начинаться и заканчиваться дополнительными номерами "0" (например, 099,00):
DecimalFormat formatter = new java.text.DecimalFormat("0000.00");
Если вы хотите правильное выравнивание без тезисов бесполезно "0" , вам придется создать свой собственный метод форматирования: он не существует в собственном Java API.
Ответ 4
В том же духе, что и Benoit, здесь предлагается класс, расширяющий DecimalFormat, который обеспечивает заданную минимальную длину левым заполнением отформатированных чисел с пробелами. Он тестировался (Java 6, 7), более общий и обеспечивает рабочий пример.
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.FieldPosition;
public class PaddingDecimalFormat extends DecimalFormat {
private int minimumLength;
/**
* Creates a PaddingDecimalFormat using the given pattern and minimum minimumLength and the symbols for the default locale.
*/
public PaddingDecimalFormat(String pattern, int minLength) {
super(pattern);
minimumLength = minLength;
}
/**
* Creates a PaddingDecimalFormat using the given pattern, symbols and minimum minimumLength.
*/
public PaddingDecimalFormat(String pattern, DecimalFormatSymbols symbols, int minLength) {
super(pattern, symbols);
minimumLength = minLength;
}
@Override
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
int initLength = toAppendTo.length();
super.format(number, toAppendTo, pos);
return pad(toAppendTo, initLength);
}
@Override
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
int initLength = toAppendTo.length();
super.format(number, toAppendTo, pos);
return pad(toAppendTo, initLength);
}
private StringBuffer pad(StringBuffer toAppendTo, int initLength) {
int numLength = toAppendTo.length() - initLength;
int padLength = minimumLength - numLength;
if (padLength > 0) {
StringBuffer pad = new StringBuffer(padLength);
for(int i = 0; i < padLength; i++) {
pad.append(' ');
}
toAppendTo.insert(initLength, pad);
}
return toAppendTo;
}
public static void main(String[] args) {
PaddingDecimalFormat intFormat = new PaddingDecimalFormat("#", 6);
for (int i = 0; i < 20; i++) {
System.out.println(intFormat.format(i) + intFormat.format(i*i*i));
}
}
}
Ответ 5
Метод, который должен ответить на вашу проблему (я написал его прямо здесь и не протестировал его, чтобы вы могли исправить ошибки, но, по крайней мере, вы поняли):
public class PaddingDecimalFormat extends DecimalFormat {
private int maxIntLength = 1;
public PaddingDecimalFormat(String pattern) {
super(pattern);
}
public void configure(Number[] numbers) {
for(Number number : numbers) {
maxIntLength = Math.max(maxIntLength, Integer.toString(number.intValue()).length());
}
}
@Override
public void format(Number number) {
int padding = maxIntLength - Integer.toString(number.intValue()).length();
StringBuilder sb = new StringBuilder();
for(int i=0; i<padding; i++) {
sb.append(' ');
}
sb.append(super.format(number));
return sb.toString();
}
}
Ответ 6
Представьте точку с запятой и System.out; форматирование, как указано выше.
printf (" ".substring (("" + Math.round (f)).length ) + formatter.format (f))
Я бы предпочел log-10-Function, чтобы рассчитать размер 999 или от 100 до 3 вместо неявного toString-вызова, но я просто нахожу логарифм naturalis.
Math.round(987.65) дает 987.
( "+ 987).length дает 3
" ___". substring (3) - пустая строка, для короткого числа (0-9) она вернет две пробелы.