没有 Math.BigInteger 的大整数的加法和减法
Addition and Subtraction of large ints without Math.BigInteger
好的,所以我被分配了一个使用堆栈的练习。此作业的挑战是创建一个程序,可以在不使用任何库或导入(例如没有 BigInteger)的情况下添加和减去非常大的整数(可能是无限大小)。
这就是我处理加法的方式:
public Stack<Integer> sum(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
int carry = 0;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int result = 0;
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
int resultDig = 0;
result = dig1 + dig2 + carry;
resultDig = result % 10;
carry = result / 10;
resultStack.push(resultDig);
}
if (carry > 0)
resultStack.push(carry);
return resultStack;
}
此方法似乎适用于某些整数而不适用于其他整数。例如,如果我输入 500 和 450,我会按预期得到 950。但是,如果我输入 500 和 45,我得到 45。
这就是我处理减法的方法(非常相似的方法):
public Stack<Integer> sub(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
boolean borrow = false;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
if (borrow = true) {
dig1 -= 1;
borrow = false;
}
if (dig1 - dig2 < 0) {
dig1 += 10;
resultStack.push(dig1 - dig2);
borrow = true;
}
}
return resultStack;
}
这有一个非常相似的问题。例如,如果我减去 50 和 45,我得到 4。如果我减去 50,000 和 45,000,我得到 4,900。
我确定我在这里遗漏了一些简单的东西,但我一遍又一遍地查看了代码,但我不确定它是什么。
我会开始看这个条件:
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false)
这意味着 "while both stacks are not empty"。但是如果你有 2 个数字位数不同(比如 500 和 45),它就会失败(因为一个堆栈将是空的而另一个不会,在处理所有数字之前离开循环)。所以你应该把条件改成"while at least one stack is not empty":
while (leadingStack.isEmpty() == false || secondStack.isEmpty() == false)
另一个提示:作为 isEmpty()
returns 布尔值,您不需要使用 ==
进行比较,您可以这样做:
while (! leadingStack.isEmpty() || ! secondStack.isEmpty())
请注意,由于一个堆栈可能是空的而另一个不是,您应该在调用之前检查它是否为空 pop
:
int dig1 = 0;
if (!leadingStack.isEmpty()) {
dig1 = leadingStack.pop();
}
int dig2 = 0;
if (!secondStack.isEmpty()) {
dig2 = secondStack.pop();
}
您的代码中有几个地方需要注意:
- 如果堆栈大小不同,则不会处理较大堆栈的剩余部分
- 返回结果堆栈时,其元素必须反转,因为最小位置的数字首先被压入(较大的位置最后)
- 在
if (borrow = true)
处相等的混合赋值运算符
- 减法不处理负数
全部在代码中:
public Stack<Integer> sum(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
int carry = 0;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
int result = dig1 + dig2 + carry;
int resultDig = result % 10;
carry = result / 10;
resultStack.push(resultDig);
}
Stack<Integer> leftStack = leadingStack.isEmpty() ? secondStack : leadingStack;
while (leftStack.isEmpty() == false) {
int dig = leftStack.pop();
if (carry > 0) {
dig += carry;
carry = 0;
}
resultStack.push(dig);
}
if (carry > 0) resultStack.push(carry);
return reverse(resultStack);
}
public Stack<Integer> sub(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
boolean borrow = false;
Stack<Integer> resultStack = new Stack<Integer>();
if (leadingStack.size() < secondStack.size()) {
// Handle negative number
}
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
if (borrow) {
dig1 -= 1;
borrow = false;
}
if (dig1 < dig2) {
dig1 += 10;
resultStack.push(dig1 - dig2);
borrow = true;
}
else {
resultStack.push(dig1 - dig2);
}
}
Stack<Integer> leftStack = leadingStack.isEmpty() ? secondStack : leadingStack;
while (leftStack.isEmpty() == false) {
int dig = leftStack.pop();
if (borrow) {
dig -= 1;
borrow = false;
}
resultStack.push(dig);
}
if (borrow) {
// Handle negative number
}
return reverse(resultStack);
}
private Stack<Integer> reverse(Stack<Integer> inStack) {
Stack<Integer> outStack = new Stack<>();
while (inStack.isEmpty() == false) outStack.push(inStack.pop());
return outStack;
}
好的,所以我被分配了一个使用堆栈的练习。此作业的挑战是创建一个程序,可以在不使用任何库或导入(例如没有 BigInteger)的情况下添加和减去非常大的整数(可能是无限大小)。
这就是我处理加法的方式:
public Stack<Integer> sum(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
int carry = 0;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int result = 0;
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
int resultDig = 0;
result = dig1 + dig2 + carry;
resultDig = result % 10;
carry = result / 10;
resultStack.push(resultDig);
}
if (carry > 0)
resultStack.push(carry);
return resultStack;
}
此方法似乎适用于某些整数而不适用于其他整数。例如,如果我输入 500 和 450,我会按预期得到 950。但是,如果我输入 500 和 45,我得到 45。
这就是我处理减法的方法(非常相似的方法):
public Stack<Integer> sub(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
boolean borrow = false;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
if (borrow = true) {
dig1 -= 1;
borrow = false;
}
if (dig1 - dig2 < 0) {
dig1 += 10;
resultStack.push(dig1 - dig2);
borrow = true;
}
}
return resultStack;
}
这有一个非常相似的问题。例如,如果我减去 50 和 45,我得到 4。如果我减去 50,000 和 45,000,我得到 4,900。
我确定我在这里遗漏了一些简单的东西,但我一遍又一遍地查看了代码,但我不确定它是什么。
我会开始看这个条件:
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false)
这意味着 "while both stacks are not empty"。但是如果你有 2 个数字位数不同(比如 500 和 45),它就会失败(因为一个堆栈将是空的而另一个不会,在处理所有数字之前离开循环)。所以你应该把条件改成"while at least one stack is not empty":
while (leadingStack.isEmpty() == false || secondStack.isEmpty() == false)
另一个提示:作为 isEmpty()
returns 布尔值,您不需要使用 ==
进行比较,您可以这样做:
while (! leadingStack.isEmpty() || ! secondStack.isEmpty())
请注意,由于一个堆栈可能是空的而另一个不是,您应该在调用之前检查它是否为空 pop
:
int dig1 = 0;
if (!leadingStack.isEmpty()) {
dig1 = leadingStack.pop();
}
int dig2 = 0;
if (!secondStack.isEmpty()) {
dig2 = secondStack.pop();
}
您的代码中有几个地方需要注意:
- 如果堆栈大小不同,则不会处理较大堆栈的剩余部分
- 返回结果堆栈时,其元素必须反转,因为最小位置的数字首先被压入(较大的位置最后)
- 在
if (borrow = true)
处相等的混合赋值运算符
- 减法不处理负数
全部在代码中:
public Stack<Integer> sum(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
int carry = 0;
Stack<Integer> resultStack = new Stack<Integer>();
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
int result = dig1 + dig2 + carry;
int resultDig = result % 10;
carry = result / 10;
resultStack.push(resultDig);
}
Stack<Integer> leftStack = leadingStack.isEmpty() ? secondStack : leadingStack;
while (leftStack.isEmpty() == false) {
int dig = leftStack.pop();
if (carry > 0) {
dig += carry;
carry = 0;
}
resultStack.push(dig);
}
if (carry > 0) resultStack.push(carry);
return reverse(resultStack);
}
public Stack<Integer> sub(Stack<Integer> leadingStack, Stack<Integer> secondStack) {
boolean borrow = false;
Stack<Integer> resultStack = new Stack<Integer>();
if (leadingStack.size() < secondStack.size()) {
// Handle negative number
}
while (leadingStack.isEmpty() == false && secondStack.isEmpty() == false) {
int dig1 = leadingStack.pop();
int dig2 = secondStack.pop();
if (borrow) {
dig1 -= 1;
borrow = false;
}
if (dig1 < dig2) {
dig1 += 10;
resultStack.push(dig1 - dig2);
borrow = true;
}
else {
resultStack.push(dig1 - dig2);
}
}
Stack<Integer> leftStack = leadingStack.isEmpty() ? secondStack : leadingStack;
while (leftStack.isEmpty() == false) {
int dig = leftStack.pop();
if (borrow) {
dig -= 1;
borrow = false;
}
resultStack.push(dig);
}
if (borrow) {
// Handle negative number
}
return reverse(resultStack);
}
private Stack<Integer> reverse(Stack<Integer> inStack) {
Stack<Integer> outStack = new Stack<>();
while (inStack.isEmpty() == false) outStack.push(inStack.pop());
return outStack;
}