【问题标题】:Align column of floats at decimal point Java在小数点处对齐浮点数列Java
【发布时间】:2013-11-10 03:50:12
【问题描述】:

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

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

String[] input = new String[3];
    System.out.format("%n%n\tEnter 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

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

【问题讨论】:

  • 使用标签。和十进制格式化程序

标签: java floating-point alignment double


【解决方案1】:

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

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%n\tEnter 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 指定用户将输入多少个数字。当然,这也可以做得更灵活一些,比如输入特殊字符时终止输入数字等。

【讨论】:

  • 感谢 Melquiades 这对我很有帮助!
【解决方案2】:

您可以编写代码来计算点之前的最大位数,例如双精度数:

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,您有点前的位数,因此您可以轻松地创建一个输出格式,点后的位数不限,而点前的位数正确。

【讨论】:

    【解决方案3】:

    要获取每个字符串中小数点的位置,您可以使用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", ""));
    }
    

    【讨论】:

    • 啊!杰出的。并且可以使用 indexOf 解决我遇到的另一个问题!谢谢 R.J
    • @WilfEngel - 很高兴这对您有所帮助,因为 2 天后您看到这个答案真是令人惊讶! :)
    【解决方案4】:

    这是一种动态方法:

    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: %s\n\n", getFormat());
            for (int i = 0; i < values.length; i++) {
                System.out.printf(String.format("Value %%d: %s\n", 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
    

    【讨论】:

      猜你喜欢
      • 2017-03-22
      • 1970-01-01
      • 2013-06-01
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2010-11-24
      • 1970-01-01
      相关资源
      最近更新 更多