如何正确对齐和格式化不同的字符串长度
How to properly align and format varying string lengths
如何将 string.format
和 printf
应用于我的输出,以便我可以根据我的作业要求对齐它?
我的方法有 3 个输入,其中 2 个是包含两个数字的 char 数组,以及一个包含它们总和的 int 数组。
我对数字和总和进行了格式化,使其成为一个字符串,中间穿插了适当的逗号。我的任务是现在对齐这些输出,以便它们始终正确对齐。问题是我不能只将列宽设置为特定数字,因为输入因用户输入而异。
例:用户输入number1和number2(最多30位数字),程序将数字相加并returns总数。
这是我的代码和当前输出:
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
如您所见,我的格式有问题。我完全不确定如何正确设置此输出的格式,以便它每次都能正确显示,即使数值不同也是如此。它的格式应该是较大的数字在较小的数字之上,然后是总行,然后是总和。
根据您的评论,数学似乎让您感到困惑。让我看看能不能帮上忙。
(你暗示这是作业,所以我不会直接给你代码,但这应该会让你走上正确的道路。我相信你可以自己实现它。)
一个数字的位数是:
Math.floor(Math.log10(x)) + 1
(见 this conversation 证明。)
用它来计算答案的长度。 (这总是最长的数字或并列最长的数字,因为您将数字加在一起。)让 ---
的行这么长。
附加到每行的前面 length of that line - length of the answer
个 space 行。
(如果你想将一定数量的 space 作为整个问题的缩进,就像你在你的例子中那样,然后附加 length of line - length of answer + indent
数量的 space s 改为每行的前面。)
将+
(space和一个加号)附加到第一行的末尾,并将
(两个space)添加到其他线路。
应该可以!
您可以使用 ArrayLists 而不是 char 数组来简化数学运算。但是你必须稍微调整一下代码。程序如下。
- 使用 getNumber() 方法将两行输入输入到两个数组列表中。 (让我们称之为 B 和 C)
- 使用求和方法将求和到第三个数组列表。(让我们调用A)
- 使用 arraylist 中的 size() 方法查找数组列表的大小。
- 比较大小并分别得到最大数组列表和其他两个数组列表之间的差异。(最大的是 A,所以得到 A-B 和 A-C)。并将大小 B 和 C 大小存储在两个变量中以备将来使用。
- 使用数组列表中的 add(index,object) 方法从 0 索引开始将 (A-B) 个空格 (" ") 添加到 B arraylist 中。(在 add(index,object) 方法中移动当前位置的元素位置(如果有)和右侧的任何后续元素)
- 对 C 数组列表也执行相同的操作。
- 使用先前存储的大小从 B 和 C 中找到数组列表的最大值,然后首先将该数组列表附加到格式化字符串中。(使用循环)
然后在“+”和“\n”之后,将第二个数组列表附加到格式字符串中。
最后将包含sum(A)的数组列表附加到格式字符串中。
- 由于我们添加了空格以使所有数组大小相同,所以格式化字符串的格式应该正确。
所以在阅读更多内容后,我意识到我试图实现的目标并不一定需要字符串格式化或 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);
如何将 string.format
和 printf
应用于我的输出,以便我可以根据我的作业要求对齐它?
我的方法有 3 个输入,其中 2 个是包含两个数字的 char 数组,以及一个包含它们总和的 int 数组。
我对数字和总和进行了格式化,使其成为一个字符串,中间穿插了适当的逗号。我的任务是现在对齐这些输出,以便它们始终正确对齐。问题是我不能只将列宽设置为特定数字,因为输入因用户输入而异。
例:用户输入number1和number2(最多30位数字),程序将数字相加并returns总数。
这是我的代码和当前输出:
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
如您所见,我的格式有问题。我完全不确定如何正确设置此输出的格式,以便它每次都能正确显示,即使数值不同也是如此。它的格式应该是较大的数字在较小的数字之上,然后是总行,然后是总和。
根据您的评论,数学似乎让您感到困惑。让我看看能不能帮上忙。
(你暗示这是作业,所以我不会直接给你代码,但这应该会让你走上正确的道路。我相信你可以自己实现它。)
一个数字的位数是:
Math.floor(Math.log10(x)) + 1
(见 this conversation 证明。)
用它来计算答案的长度。 (这总是最长的数字或并列最长的数字,因为您将数字加在一起。)让 ---
的行这么长。
附加到每行的前面 length of that line - length of the answer
个 space 行。
(如果你想将一定数量的 space 作为整个问题的缩进,就像你在你的例子中那样,然后附加 length of line - length of answer + indent
数量的 space s 改为每行的前面。)
将+
(space和一个加号)附加到第一行的末尾,并将(两个space)添加到其他线路。
应该可以!
您可以使用 ArrayLists 而不是 char 数组来简化数学运算。但是你必须稍微调整一下代码。程序如下。
- 使用 getNumber() 方法将两行输入输入到两个数组列表中。 (让我们称之为 B 和 C)
- 使用求和方法将求和到第三个数组列表。(让我们调用A)
- 使用 arraylist 中的 size() 方法查找数组列表的大小。
- 比较大小并分别得到最大数组列表和其他两个数组列表之间的差异。(最大的是 A,所以得到 A-B 和 A-C)。并将大小 B 和 C 大小存储在两个变量中以备将来使用。
- 使用数组列表中的 add(index,object) 方法从 0 索引开始将 (A-B) 个空格 (" ") 添加到 B arraylist 中。(在 add(index,object) 方法中移动当前位置的元素位置(如果有)和右侧的任何后续元素)
- 对 C 数组列表也执行相同的操作。
- 使用先前存储的大小从 B 和 C 中找到数组列表的最大值,然后首先将该数组列表附加到格式化字符串中。(使用循环)
然后在“+”和“\n”之后,将第二个数组列表附加到格式字符串中。
最后将包含sum(A)的数组列表附加到格式字符串中。
- 由于我们添加了空格以使所有数组大小相同,所以格式化字符串的格式应该正确。
所以在阅读更多内容后,我意识到我试图实现的目标并不一定需要字符串格式化或 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);