处理大数字和溢出

时间:2013-08-09 17:29:19

标签: c algorithm

我得到了一个N​​个元素的数组,我需要在这个数组中找到索引P. 0到P范围内的值之和等于P + 1到N-1范围内的值之和。

数组中每个元素的值可以是-2147483648到2147483647和 N最大可达10000000。

鉴于此,如何在添加每个值以查找索引P?

时确保没有溢出

3 个答案:

答案 0 :(得分:4)

为确保不会出现溢出,请使用int32_tint64_t

值范围[-2147483648 ... 2147483647]与int32_t范围匹配。您也可以使用int64_t,但10000000的数组值得考虑空间。

由于任何 10,000,000值的总和不超过int64_t的范围,请使用int64_t执行所有添加。

#include <stdint.h>
size_t foo(const int32_t *value, size_t N) {
  int64_t sum = 0;
  ...
  sum += value[i];
  ...
}

BTW:确信可以获得不需要添加64位加法的解决方案 [编辑]无法导出简单的int32_t解决方案,但提出了:

size_t HalfSum(const int32_t *value, size_t N) {
  // find sum of entire array    
  int64_t ArraySum = 0;
  size_t P;
  for (P = 0; P < N; P++) {
    ArraySum += value[P];
  }

  // compute sum again, stopping when it is half of total
  int64_t PartialSum = 0;
  for (P = 0; P < N; P++) {
    PartialSum += value[P];
    if ((PartialSum * 2) == ArraySum) {
      return P;
    }
  }

  return N;  // No solution (normally P should be 0 ... N-1)
}

答案 1 :(得分:1)

使用64位整数进行计算。要使用的最佳类型为int64_t,因为long不能保证为64位(您必须#include <stdint.h>才能使其可用)。

编辑:Pascal Cuoq是对的:long long确实提供了64位保证,并且不需要包含(但它可能长于64位),所以它只是{{1如果你想要便携,你必须避免使用类型。

答案 2 :(得分:-1)

在最坏的情况下,P + 1 = N-1。由于对于任何单个数字,ynumber的最大值只能是2147483647或-2147483647,这意味着在最坏的情况下,P将是最大值或最小值。在其他情况下,P仍然是一个长整数。因此,在最坏的情况下你应该只需要使用long(因为如果你的更糟糕的情况预期结果是P是任何单个数字可能的最大可能数字很长。

为了确保你不必使用更大的东西,将负值与正值配对,这样你就可以保持在长的溢出之下。

想象一下,我们有3个数字,一个是b和c。如果a + b溢出long数据类型,我们知道c将不是P.

现在假设我们有4个数字,a,b,c,d使得a + b + c = d(意思是d是P),如果a + b会溢出很长,则意味着 1)c不能是P. 2)存在a + b + c的组合,使得long的数据类型不需要溢出。

例如,a是max long,b是min long,c是min long,d是0,那么a + c + b = d将是正确的操作组合,以便不使用更大的数据类型我们可以尝试a + c,因为我们知道c不能是P,因为a + b会溢出很长的&gt; P.的最大可能值