如何正确对齐和格式化变化的字符串长度

时间:2018-07-06 21:01:00

标签: java printf string-formatting

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

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

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

Ex:用户输入数字1和数字2(最大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

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

3 个答案:

答案 0 :(得分:1)

因此,在阅读了更多内容之后,我意识到我要实现的目标并不一定需要字符串格式或printf语句。最后,就像上面的建议一样,我只是用多个打印语句格式化了输出。绝对不是要看的最漂亮的代码,但是它为我提供了我想要的确切输出。

这是达到目的的代码:

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);

答案 1 :(得分:0)

根据您的评论,似乎数学使您大跌眼镜。让我看看能否帮忙。

(您暗示这是家庭作业,因此我不会从字面上给您代码,但这应该可以使您走上正确的道路。我相信您可以自己实现它。)

数字中的位数是:

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

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

使用它来找到答案的长度。 (由于您要将数字加在一起,所以它总是最长的数字或最长的数字。)使---行如此长。

追加到每行length of that line - length of the answer个空格的开头。

(如果您想像整个示例那样在整个问题上有一定数量的空格作为缩进,请在每行的前面附加length of line - length of answer + indent个空格。)

在第一行末尾添加+(空格和加号),在其他行末尾添加(两个空格)。

应该可以!

答案 2 :(得分:0)

您可以使用ArrayLists代替char数组来简化数学。但是您必须稍微调整一下代码。这是过程。

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

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

  • 当我们添加空格以使所有数组具有相同的大小时,格式化后的字符串应格式正确。