如何在不使用 BigInteger 数据类型的情况下将两个非常大的数字相加,而不管它们在 Java 中的大小?
How to add two very large numbers irrespective of their size in Java without using BigInteger data type?
我需要在不使用 BigInteger
的情况下将两个非常大的数字相加。我采用了两个字符串参数,但下面的代码仅适用于长度相等的字符串,否则会抛出 IndexOutOfBoundsException
。我怎样才能通过添加大数字而不考虑它们的长度来解决这个问题?
public static String add(String a, String b) {
int carry = 0;
String result = "";
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
您可以在较短的字符串前加上零,使其与另一个数字的长度相匹配:
private static String leftPad(String s, int length) {
if (s.length() >= length)
return s;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length - s.length(); i++)
sb.append("0");
return sb.toString() + s;
}
public static String add(String originalA, String originalB) {
int maxLength = Math.max(originalA.length(), originalB.length());
String a = leftPad(originalA, maxLength);
String b = leftPad(originalB, maxLength);
... rest of your method
您可以像这样用零填充字符串:
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
这将添加前导空格以填充 "gap",然后用零替换它们。
Class:
public class Mission09 {
public static void main(String[] args) {
System.out.println(add("1", "1333"));
}
public static String add(String a, String b) {
int carry = 0;
String result = "";
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
}
I/O:
System.out.println(add("1", "1333"));
1334
System.out.println(add("12222", "1333"));
13555
不需要用零填充任何参数。另外,为了获得更好的性能,请不要使用 String + String
.
为结果创建一个char[]
。由于结果可能比最长的输入长 1,因此以该大小创建它。
然后从输入字符串的末尾开始迭代,设置结果中的每个字符。
然后消除任何前导零,因为输入没有溢出或输入有前导零。
最后,使用 String(char[] value, int offset, int count)
构造函数从 char[]
创建一个 String
。
像这样:
public static String add(String a, String b) {
int i = a.length();
int j = b.length();
int k = Math.max(i, j) + 1; // room for carryover
char[] c = new char[k];
for (int digit = 0; k > 0; digit /= 10) {
if (i > 0)
digit += a.charAt(--i) - '0';
if (j > 0)
digit += b.charAt(--j) - '0';
c[--k] = (char) ('0' + digit % 10);
}
for (k = 0; k < c.length - 1 && c[k] == '0'; k++) {/*Skip leading zeroes*/}
return new String(c, k, c.length - k);
}
测试
public static void main(String[] args) {
test("1234", "2345"); // test equal-sized inputs, no carry-over
test("12345", "12345"); // test equal-sized inputs, with carry-over
test("54321", "54321"); // test equal-sized inputs, longer result
test("99999", "99999"); // test max result
test("5", "1234"); // test odd-sized inputs, no carry-over
test("5", "12345"); // test odd-sized inputs, with carry-over
test("1", "99999"); // test with a carry-over to longer result
test("001", "00002"); // test leading zeroes in input are eliminated
test("000", "00000"); // test leading zero removal leaves 1 zero
}
public static void test(String a, String b) {
// Test add is commutative, i.e. a+b = b+a
System.out.printf("%s + %s = %s = %s%n", a, b, add(a, b), add(b, a));
}
输出
1234 + 2345 = 3579 = 3579
12345 + 12345 = 24690 = 24690
54321 + 54321 = 108642 = 108642
99999 + 99999 = 199998 = 199998
5 + 1234 = 1239 = 1239
5 + 12345 = 12350 = 12350
1 + 99999 = 100000 = 100000
001 + 00002 = 3 = 3
000 + 00000 = 0 = 0
我需要在不使用 BigInteger
的情况下将两个非常大的数字相加。我采用了两个字符串参数,但下面的代码仅适用于长度相等的字符串,否则会抛出 IndexOutOfBoundsException
。我怎样才能通过添加大数字而不考虑它们的长度来解决这个问题?
public static String add(String a, String b) {
int carry = 0;
String result = "";
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
您可以在较短的字符串前加上零,使其与另一个数字的长度相匹配:
private static String leftPad(String s, int length) {
if (s.length() >= length)
return s;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length - s.length(); i++)
sb.append("0");
return sb.toString() + s;
}
public static String add(String originalA, String originalB) {
int maxLength = Math.max(originalA.length(), originalB.length());
String a = leftPad(originalA, maxLength);
String b = leftPad(originalB, maxLength);
... rest of your method
您可以像这样用零填充字符串:
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
这将添加前导空格以填充 "gap",然后用零替换它们。
Class:
public class Mission09 {
public static void main(String[] args) {
System.out.println(add("1", "1333"));
}
public static String add(String a, String b) {
int carry = 0;
String result = "";
int longestString = Math.max(a.length(), b.length());
a = String.format("%1$" + longestString + "s", a).replace(' ', '0');
b = String.format("%1$" + longestString + "s", b).replace(' ', '0');
for (int i = a.length() - 1; i >= 0; i--) {
int digitA = a.charAt(i) - 48;
int digitB = b.charAt(i) - 48;
int resultingNumber = digitA + digitB + carry;
if (resultingNumber >= 10) {
result = (resultingNumber % 10) + result;
carry = 1;
} else {
result = resultingNumber + result;
carry = 0;
}
}
if (carry > 0) {
result = carry + result;
}
return result;
}
}
I/O:
System.out.println(add("1", "1333"));
1334
System.out.println(add("12222", "1333"));
13555
不需要用零填充任何参数。另外,为了获得更好的性能,请不要使用 String + String
.
为结果创建一个char[]
。由于结果可能比最长的输入长 1,因此以该大小创建它。
然后从输入字符串的末尾开始迭代,设置结果中的每个字符。
然后消除任何前导零,因为输入没有溢出或输入有前导零。
最后,使用 String(char[] value, int offset, int count)
构造函数从 char[]
创建一个 String
。
像这样:
public static String add(String a, String b) {
int i = a.length();
int j = b.length();
int k = Math.max(i, j) + 1; // room for carryover
char[] c = new char[k];
for (int digit = 0; k > 0; digit /= 10) {
if (i > 0)
digit += a.charAt(--i) - '0';
if (j > 0)
digit += b.charAt(--j) - '0';
c[--k] = (char) ('0' + digit % 10);
}
for (k = 0; k < c.length - 1 && c[k] == '0'; k++) {/*Skip leading zeroes*/}
return new String(c, k, c.length - k);
}
测试
public static void main(String[] args) {
test("1234", "2345"); // test equal-sized inputs, no carry-over
test("12345", "12345"); // test equal-sized inputs, with carry-over
test("54321", "54321"); // test equal-sized inputs, longer result
test("99999", "99999"); // test max result
test("5", "1234"); // test odd-sized inputs, no carry-over
test("5", "12345"); // test odd-sized inputs, with carry-over
test("1", "99999"); // test with a carry-over to longer result
test("001", "00002"); // test leading zeroes in input are eliminated
test("000", "00000"); // test leading zero removal leaves 1 zero
}
public static void test(String a, String b) {
// Test add is commutative, i.e. a+b = b+a
System.out.printf("%s + %s = %s = %s%n", a, b, add(a, b), add(b, a));
}
输出
1234 + 2345 = 3579 = 3579
12345 + 12345 = 24690 = 24690
54321 + 54321 = 108642 = 108642
99999 + 99999 = 199998 = 199998
5 + 1234 = 1239 = 1239
5 + 12345 = 12350 = 12350
1 + 99999 = 100000 = 100000
001 + 00002 = 3 = 3
000 + 00000 = 0 = 0