2014-01-21 62 views
10

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

我最初的做法是伪代码如下:

  1. 如果第二个字符串的第一个字符是“ - ”然后设定减标记。
  2. 将每个字符串转换为一个整数数组,每个数字一个。
  3. 用零填充最短的数组和左边的数组,使得两个数组的大小相同。
  4. 循环遍历数组中的每个索引(从最低有效位数字到最高有效位数字)执行加/减运算,并使用进位将溢出运送到下一位数字。
  5. 检查进位以添加最后的数字。

我的算法适用于正数,但对负数给出了非常不正确的结果。我试图在纸上做这件事,但我似乎无法理解如何逐位减法。

我目前的算法步骤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; 
} 
+2

你能举一个例子输入和一个错误的输出例子吗? –

+0

当然。当number1是'1'而number2是'-10'时,我当前的算法给出了-91'。 – DanielGibbs

+0

在纸上试一下简单的例子:11-3。我们会这样做:3 + 8 =(1)1,所以写8,保留一个。然后进行+ 1 = 1,无事可做。你的算法正在做非常不同的事情。 – PMF

回答

6

如果符号为负,数字2比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; 
} 
3

如果最后提的是-1,那么就意味着你必须添加-1 * 10^(number of digits)答案。

01 
-10 
--- 
91 

And Carry = -1。因此,你必须添加-100到91才能得到实际的答案。

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

+0

没错,但我该如何做数位数字?我不能对整个数字进行操作,因为它的长度是任意的。 – DanielGibbs

+0

您可以通过比较数字来检查哪个数字更大。如果数字的位数相同,则比较数位。用'1'和'-10'做的 –

2

确保在做减法运算时,较大的数字在number1中,否则您会得到奇怪的答案。如果需要,切换编号1和编号2并根据需要考虑负数。否则对我来说看起来没问题。

因此,例如1 + -10应该是10 - 1,而结果的负值-9。

+0

看起来很容易。想象一下,如果(A> = b)和B是-ve,数字是'12352432'和'-345231234' – Baby

3

你可以把它包:

if(A>=B): 
    calculate A-B 
else: 
    calculate -(B-A) 
+0

,我们需要执行ADD(A,B)。 –

1

那么你可能只是切换+/-号。

例如,如果num1 = 1,num2 = -10,而不是做(1-10)并得到-9, ,您可以尝试 - (10-1)来代替。 因为看起来你的算法可以正常运行,如果num1 = 10,并且num2 = -1。

所以基本上你会用num1切换num2,如果它的幅度大于num1,并且否定最终结果。

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