在小数点对齐浮点数列 Java



我想在小数点对齐一列浮点数。我知道如果您限制小数点后的点数,这很容易做到,但我希望用户能够输入无限数量和长度的浮点数。

这是我的程序处理浮点对齐的部分:

String[] input = new String[3];
    System.out.format("%n%ntEnter three floating point numbers%n");
    for (int i=0;i<3;i++)
        input[i] = in.nextLine();
    System.out.format("tHere they are lined up on their decimal point%n");
/*This is used to find decimal location in each string*/
    int[] decLoc = new int[3];
    for (int i=0; i<3; i++)
    {
        for(int j=1; j<=input[i].length();j++)
            if(input[i].charAt(j-1) == '.') 
                decLoc[i] = j;
    }
/*print 5 spaces before number if the decimal is at place 0, 4 spaces for 1...*/ 
    for(int i=0;i<3;i++)
    {
        if(decLoc[i]==0) System.out.print("      ");
        else if(decLoc[i]==1) System.out.print("     ");
        else if(decLoc[i]==2) System.out.print("    ");
        else if(decLoc[i]==3) System.out.print("   ");
        else if(decLoc[i]==4) System.out.print("  ");
        else if(decLoc[i]==5) System.out.print(" ");
        System.out.println(input[i]);
    }

输出:

        Enter three floating point numbers
3265.3265
23.365
254.3256
        Here they are lined up on their decimal point
 3265.3265
   23.365
  254.3256

需要更好的解决方案来对齐不同长度的浮子。

为了使其灵活,您只能在已有的代码中添加几行代码。首先,让我们找出点前最长的位数是多少:

int LENGTH = 3;
int longestCountBeforeDecimalPoint = 0;
for (int i=0; i<LENGTH; i++) {
    int indexOfDot = input[i].indexOf(".");
    if (longestCountBeforeDecimalPoint < indexOfDot) {
        longestCountBeforeDecimalPoint = indexOfDot;
    }
}

然后,不要使用"if"条件,而是添加此行,它将利用您之前找到的小数点的位置,并且基本上执行您正在执行的操作,但具有更大的灵活性:

for (int j=0; j<longestCountBeforeDecimalPoint - decLoc[i] + 1; j++) {
    System.out.print(" ");
}

完整代码:

Scanner in = new Scanner(System.in);
int LENGTH = 3;
String[] input = new String[LENGTH];
System.out.format("%n%ntEnter three floating point numbers%n");
for (int i=0; i<LENGTH; i++)
    input[i] = in.nextLine();
//finds the longest number of digits before the dot
int longestCountBeforeDecimalPoint = 0;
for (int i=0; i<LENGTH; i++) {
    int indexOfDot = input[i].indexOf(".");
    if (longestCountBeforeDecimalPoint < indexOfDot) {
        longestCountBeforeDecimalPoint = indexOfDot;
    }
}
System.out.format("tHere they are lined up on their decimal point%n");
/*This is used to find decimal location in each string*/
int[] decLoc = new int[LENGTH];
for (int i=0; i<LENGTH; i++)
{
    //as R.J noted below, finding dot place can be done like this
    decLoc[i] = input[i].indexOf('.');
}
/*print 5 spaces before number if the decimal is at place 0, 4 spaces for 1...*/ 
for(int i=0; i<LENGTH; i++)
{
    //add spaces
    for (int j=0; j<longestCountBeforeDecimalPoint - decLoc[i] + 1; j++) {
        System.out.print(" ");
    }
    System.out.println(input[i]);
}

在输出中,您将根据要求将所有数字对齐在点位置。

用随机生成的 10000 个数字进行测试,所有数字都在点位置对齐。

LENGTH 指定用户将输入的号码数。当然,这也可以更加灵活,例如在输入某些特殊字符时终止输入数字等。

你可以只编写代码来计算点前的最大位数,一个双精度的例子:

double[] theNumbers = new double[5];
double[0] = 1324.5314564;
double[1] = 24.4;
double[2] = 0.2574;
double[3] = -56.77;
double[4] = -2.0;
int maxDigitsBeforeDot = 0;
int actExponent = 0;
boolean found = false;
while(!found) {
    found = true;
    for(double act : theNumbers) {
        if(Math.abs(act) >= Math.pow(10,actExponent)) { found = false; }
    }
    actualExponent++;
}
maxDigitsBeforeDot = actExponent;

使用maxDigitsBeforeDot,您可以在点之前获得位数,因此您可以轻松创建输出格式,点后有无限位,在点之前有正确的位数。

要获取每个字符串中小数点的位置,您可以使用 indexOf() of 方法。这样,您可以填充decLoc数组。

for (int i = 0; i < 3; i++) {
    decLoc[i] = input[i].indexOf('.');
}

若要打印,不如让if执行此操作,您可以使用一个方法,该方法根据传递的参数打印空格的编号,并且可以在打印数据的for内调用此方法。

void printSpaces(int n) {
    System.out.print(String.format("%" + n + "s", ""));
}

这是一种动态方法:

public class FloatFormatter {
    String[] values;
    String format;
    public static void main(String[] args) {
        String[] input = new String[] {
                "3265.3265999999",
                "8823999.365",
                "254.3256",
                "123"};
        FloatFormatter f = new FloatFormatter(input);
        f.printFormattedValues();
    }
    public FloatFormatter(String[] values) {
        setValues(values);
    }
    public void setValues(String[] values) {
        this.values = values;
        updateFormat();
    }
    public String getFormat() {
        return format;
    }
    public void printFormattedValues() {
        System.out.printf("Float format: %snn", getFormat());
        for (int i = 0; i < values.length; i++) {
            System.out.printf(String.format("Value %%d: %sn", getFormat()),
                    i, Double.parseDouble(values[i]));
        }
    }
    protected void updateFormat() {
        byte[] lenAndFigs = getLengthAndSigFigs();
        format = String.format("%%%d.%df", lenAndFigs[0], lenAndFigs[1]);
    }
    private final byte[] getLengthAndSigFigs() {
        byte length = 0, sigFigs = 0;
        String[] parts;
        for (String value : values) {
            parts = value.split("\.");
            length = (byte) Math.max(length, parts[0].length());
            if (parts.length > 1)
                sigFigs = (byte) Math.max(sigFigs, parts[1].length());
        }
        return new byte[] { (byte) (length + sigFigs + 1), sigFigs };
    }
}

输出:

浮点格式: %18.10f

Value 0:    3265.3265999999
Value 1: 8823999.3650000000
Value 2:     254.3256000000
Value 3:     123.0000000000

最新更新