【问题标题】:How to properly align and format varying string lengths如何正确对齐和格式化不同的字符串长度
【发布时间】:2018-12-15 11:38:07
【问题描述】:

如何将string.formatprintf 应用到我的输出中,以便根据我的分配要求对其进行对齐?

我的方法有 3 个输入,其中 2 个是保存两个数字的 char 数组,另一个是保存它们总和的 int 数组。

我已经对数字和总和进行了格式化,使其成为一个带有适当逗号的字符串。我的任务是现在对齐这些输出,以便它们始终正确对齐。问题是我不能只将列宽设置为特定数字,因为输入因用户输入而异。

例如:用户输入 number1 和 number2(最大值为 30 位),程序将数字相加并返回总数。

这是我的代码和当前输出:

import java.util.Scanner;
import java.util.Arrays;
public class Lab8{
    public static void main(String[] args){
        char[] num1 = {'9','2','3','8','7','4','8','6','7','2','9'};
        char[] num2 = {'3','9','9','8','3','9','2','8','3','4','9','4','5','8'};
        //getNumber("First Number: ");
        //getNumber("Second Number: ");
        //printArray(num1);
        //System.out.println();
        //printArray(num2);
        int[] finalTotal = sumArrays(num1,num2);
        //sumArrays(num1, num2);

        printOutput(num1, num2, finalTotal);

    }
    //-------- 
   /** Read a line of message from keyboard and return it as an array of char
      @return: Array of characters 
     */
    public static char[] getNumber(String msg){
        String myMessage;
        System.out.print(msg);
        Scanner input = new Scanner(System.in);
        myMessage = input.nextLine();// Read a line of message
        return myMessage.toCharArray();
   }   


   public static int[] sumArrays(char[] num1, char[] num2){

        int sum= 0, carry = 0, size = 0, min = 0;

        if(num1.length > num2.length){
            size = num1.length + 1;
            min = num2.length;
        }else{
            size = num2.length + 1;
            min = num1.length;
        }   

        int[] sumArray = new int[size];


        int i = num1.length-1;
        int j = num2.length-1;
        int k = size-1;

        while(i >= 0 && j >=0){

           sum = Character.getNumericValue(num1[i]) + Character.getNumericValue(num2[j]) + carry;
           i--;
           j--;
           sumArray[k] = sum % 10;
           sum = sum / 10;
           carry = sum % 10;
           k--;

       }   

        while(i >= 0){

            sum = Character.getNumericValue(num1[i]) + carry;
            sumArray[k] = sum % 10;
            sum = sum / 10;
            carry = sum % 10;
            i--;
            k--;

        }

        while( j >= 0){

            sum = Character.getNumericValue(num2[j]) + carry;
            sumArray[k] = sum % 10;
            sum = sum / 10;
            carry = sum % 10;
            j--;
            k--;

        }   

        sumArray[k] = carry;

        int[] finalSum = new int[sumArray.length-1];

        finalSum = printArray(sumArray);

        return finalSum;

   }  

      public static void printOutput(char[] num1, char[] num2, int[] sum){

        char[] largest = new char[1];
        char[] smallest = new char[1];
        char[] tmp = new char[1];

        if(num2.length > num1.length){
            largest = num2;
            smallest = num1;
        }else{
            largest = num1;
            smallest = num2;
        }     

        String number1 = formatString(largest);
        String number2 = formatString(smallest);
        String total = formatString(sum);


        System.out.printf("%s%n", number1 + " +");

        for(int i = 0; i < (number1.length() -  number2.length()); i++){
            System.out.print(" ");
        }   
        System.out.printf("%s%n%s%n%s", number2, totalLine(sum),total);

   }  


   public static String formatString(char[] num){

       String formattedString = "";

       for(int i = 0; i < num.length; i++){

           if(i == 0){
                formattedString = num[num.length-1-i] + formattedString;
                continue;
            }

            if(i % 3 == 0){
                formattedString = "," + formattedString;
            }

            formattedString = num[num.length-1-i] + formattedString;
       }   

       return formattedString;

   }  


    public static String totalLine(int[] num){

        String totalLine = "";

        for(int i = 0; i < num.length; i++){

            totalLine = "- " + totalLine;

        }   

        return totalLine;

    }   


    public static String formatString(int[] num){

        String formattedString = "";

       for(int i = 0; i < num.length; i++){

           if(i == 0){
                formattedString = num[num.length-1-i] + formattedString;
                continue;
            }

            if(i % 3 == 0){
                formattedString = "," + formattedString;
            }

            formattedString = num[num.length-1-i] + formattedString;
       }   

       return formattedString;

   }  


   public static int[] printArray(int[] arr){
        int[] sum = new int[arr.length-1];
        if(arr[0] == 0){
           for(int i = 1; i < arr.length; i++){
                sum[i-1] = arr[i];
            }
        }else{
            for(int i = 0; i < arr.length; i++){
                sum[i] = arr[i];
            }   
        }   
        return sum;
    }

}

输出(错误)

39,983,928,349,458 +
92,387,486,729
- - - - - - - - - - - - - - 
40,076,315,836,187

输出(正确方式)

       39,983,928,349,458 + 
           92,387,486,729
     --------------------
       40,076,315,836,187

如您所见,我的格式有缺陷。我完全不确定如何正确格式化此输出,以便每次都能正确显示,即使数值不同。它应该格式化为较大的数字在较小的数字之上,然后是总和,然后是总和。

【问题讨论】:

  • 您查看过printf 及其格式说明符的文档吗?即使是对右对齐 Java printf 的简单搜索似乎也是一个好的开始,例如,我发现了这个:stackoverflow.com/questions/15961130/…
  • 我以前看过这个,但我看不出它对我有什么帮助。可能是我想的不够仔细。
  • 嗯。接受的答案具有带宽度的字符串格式;也许我误解了。或者也许你没有阅读足够的内容并尝试任何事情。耸耸肩。无论如何,我很确定您可以对 Java 字符串进行右对齐,并且仅搜索该字符串即可找到答案。
  • 您可以尝试在最小的开头插入空格。要添加的空格数 = maximum.length-smallest,length
  • 你能把完整的代码贴在这里。 (formatString 和 totalLine 方法以及如何调用 printOutput 计算总和。

标签: java printf string-formatting


【解决方案1】:

所以在阅读了更多内容后,我意识到我想要实现的目标并不一定需要字符串格式或 printf 语句。我最终像之前建议的 cmets 和答案一样,只是使用多个打印语句格式化输出。这绝对不是最漂亮的代码,但它给了我想要的确切输出。

这就是成功的代码:

System.out.println("  " + number1 + " +");
for(int i = 0; i < (number1.length() - number2.length()); i++){
    System.out.print(" ");
}
System.out.println("  " + number2);
System.out.print(" ");
for(int j = 0; j < ((number1.length() - number2.length())+ number2.length()+1); j++){
    System.out.print("-");
}
System.out.println();
System.out.print("  " + total);

【讨论】:

  • 或者您可以根据长度构建格式字符串,例如,“%20s”空格填充和右对齐,因此您将获取第一个数字,附加“+”,取您的第二个数字并附加等效空格,并构建适当的格式字符串。 YMMV。在引擎盖下都是相同的操作。
【解决方案2】:

您可以使用 ArrayLists 而不是 char 数组来简化数学运算。但是你必须稍微调整一下代码。这是程序。

  • 使用 getNumber() 方法在两个数组列表中获取两行输入。 (我们叫 B 和 C)
  • 使用 sum 方法将总和放到第三个数组列表中。(我们称之为 A)
  • 使用 arraylist 中的 size() 方法查找数组列表的大小。
  • 比较大小并分别获得最大数组列表和其他两个数组列表之间的差异。(最大的应该是 A,所以得到 A-B 和 A-C)。并将尺寸 B 和 C 的尺寸存储在两个变量中以备将来使用。
  • 使用数组列表中的 add(index,object) 方法将 (AB) 空格数 (" ") 添加到从 0 索引开始的 B 数组列表中。(在 add(index,object) 方法中,移动当前位于该位置的元素(如果有的话)以及右边的任何后续元素)
  • 也对 C 数组列表执行相同操作。
  • 使用先前存储的大小从 B 和 C 中找到 Array List 的最大值,并首先将该数组列表附加到格式化的字符串中。(使用循环)
  • 然后在“+”和“\n”之后,将第二个数组列表追加到格式字符串中。

  • 最后将包含 sum(A) 的数组列表追加到格式字符串中。

  • 由于我们添加了空格以使所有数组大小相同,因此格式化后的字符串应该格式正确。

【讨论】:

    【解决方案3】:

    根据您的 cmets,数学似乎在绊倒您。让我看看能不能帮上忙。

    (你暗示这是家庭作业,所以我不会直接给你代码,但这应该会让你走上正确的道路。我相信你可以自己实现它。)

    一个数字的位数是:

    Math.floor(Math.log10(x)) + 1
    

    (有关证明,请参阅 this conversation。)

    使用它来查找答案的长度。 (这总是最长的数字或并列最长的数字,因为您将数字加在一起。)将您的 ---s 行延长至此。

    在每行前面追加length of that line - length of the answer个空格。

    (如果您想在整个问题上使用一定数量的空格作为缩进,就像您在示例中所做的那样,则将length of line - length of answer + indent 数量的空格附加到每行的前面。)

    +(空格和加号)附加到第一行的末尾,将(两个空格)附加到其他行。

    应该可以!

    【讨论】:

      猜你喜欢
      • 2014-10-12
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 2021-07-15
      • 2017-09-25
      • 2013-10-10
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多