逐位减去两个整数

时间:2014-01-21 05:42:17

标签: java algorithm integer subtraction

我最近得到了一个编程难题,我无法为我的生活找到一个满意的答案:计算由字符串给出的两个任意大整数的总和,其中第二个整数可能是负数。这是在Java中完成的,不使用任何BigIntegerBigNumber等类。

我的初始方法是伪代码:

  1. 如果第二个字符串的第一个字符是' - ',则设置减法标记。
  2. 将每个字符串转换为整数数组,每个数字一个。
  3. 用零扩展最短的数组和左边的pad,这样两个数组的大小都相同。
  4. 循环遍历数组的每个索引(从最低有效数字到最高有效数字)执行加/减,并使用进位将溢出进行到下一个数字。
  5. 检查进位以添加任何最后的数字。
  6. 我的算法适用于正数,但对负数给出了非常不正确的结果。我试图在纸上解决这个问题,但我似乎无法理解如何逐位减法。

    我目前对步骤4和5的算法如下:

    int[] result = new int[number1.length];
    int carry = 0;
    for(int i = number1.length - 1; i >= 0; i--) {
        int newDigit = (negative ? number1[i] - number2[i] : number1[i] + number2[i]);
        newDigit += carry;
        if (newDigit >= 10) {
            carry = 1;
            newDigit -= 10;
        } else if (newDigit < 0) {
            carry = -1;
            newDigit += 10;
        } else {
            carry = 0;
        }
        result[i] = newDigit;
    }
    // Convert result back into a string.
    String resultString = intArrayToString(result);
    // Apply carry.
    if(carry == 1) {
        return "1" + resultString;
    } else if(carry == -1) {
        return "-" + resultString;
    } else {
        return resultString;
    }
    

5 个答案:

答案 0 :(得分:6)

如果符号为负数且number2大于number1,则可以简单地交换这些整数数组。

您可以尝试这样的事情:

boolean swap = false;
for(int j = 0; j < number1.length && negative; j++){
    if(number2[j] > number1[j]){
        swap = true;                
        int temp[] = number1;
        number1 = number2;
        number2 = temp;
        break;
    } else if(number1[j] > number2[j]){
        break;
    }
}

int[] result = new int[number1.length];
int carry = 0;
for(int i = number1.length - 1; i >= 0; i--) {
    int newDigit = (negative ? number1[i] - number2[i] : number1[i] + number2[i]);

    newDigit += carry;
    if (newDigit >= 10) {
        carry = 1;
        newDigit -= 10;
    } else if (newDigit < 0) {
        carry = -1;
        newDigit += 10;
    } else {
        carry = 0;
    }
    result[i] = newDigit;
}

// Convert result back into a string.
String resultString = "";
for(int j = 0; j <result.length; j++){
    resultString += (result[j] + "");
}

// Apply carry.
if(carry == 1) {
    return "1" + resultString;
} else if(carry == -1 || swap) {//if swap is set sign is - 
    return "-" + resultString;
} else {
    return resultString;
}

答案 1 :(得分:3)

如果最后一个进位为-1,则表示您必须在答案中添加-1 * 10^(number of digits)

 01
-10
---
 91

并且Carry = -1。因此,您必须添加-100到91才能得到实际答案。

解决方案只是从较大的数字中减去较小的数字,然后相应地添加符号。

答案 2 :(得分:3)

你可以用:

包装它
if(A>=B):
    calculate A-B
else:
    calculate -(B-A)

答案 3 :(得分:2)

确保在进行减法时,较大的数字在number1中,否则您将获得奇数答案。如果需要,请切换number1和number2,并根据需要考虑负数。否则对我来说没问题。

所以例如1 + -10应该是10 - 1,结果是负数,-9。

答案 4 :(得分:1)

你可以切换+/-符号。

例如,如果num1 = 1,num2 = -10,而不是执行(1-10)并获取-9, 你可以尝试做 - (10-1)而不是。 因为如果num1 = 10,并且num2 = -1,那么你的算法似乎可以正常运行。

所以基本上你会用num1切换num2,如果它的数量大于num1,则取消最终结果。

* 好的,有人在评论的时候做了代码。