数组大数的均衡指数,如何防止溢出
Equilibrium index of an array of large numbers, how to prevent overflow?
>问题陈述:
数组的均衡指数是数组的索引,使得较低索引处的元素总和等于较高索引处的元素总和。
例如,在 {-7, 1, 5, 2, -4, 3, 0} 中,3 是均衡指数,因为: -7 + 1 + 5 = -4 + 3 + 0
编写一个函数,给定一个整数向量,返回其平衡指数(如果有的话)。假设向量可能很长。
问题:
我发现的所有解决方案(有效)都是基于这样一个事实,即给定所有元素的总和和一个部分的当前运行总和,我们可以通过扣除剩余部分元素的总和来获得。我不认为解决方案是正确的,因为如果我们为大向量提供MAX_INT元素,元素的总和将导致溢出。
如何解决溢出问题?
建议解决方案的参考,所有这些都无法解决溢出问题(我只指C++实现,据我所知,在Java中存在解决它的BigInteger类)
http://blog.codility.com/2011/03/solutions-for-task-equi.html补充材料:
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
template <typename T>
std::vector<size_t> equilibrium(T first, T last)
{
typedef typename std::iterator_traits<T>::value_type value_t;
value_t left = 0;
value_t right = std::accumulate(first, last, value_t(0));
std::vector<size_t> result;
for (size_t index = 0; first != last; ++first, ++index)
{
right -= *first;
if (left == right)
{
result.push_back(index);
}
left += *first;
}
return result;
}
template <typename T>
void print(const T& value)
{
std::cout << value << "n";
}
int main()
{
const int data[] = { -7, 1, 5, 2, -4, 3, 0 };
std::vector<size_t> indices(equilibrium(data, data + 7));
std::for_each(indices.begin(), indices.end(), print<size_t>);
}
简短的回答是,最终它无法完全治愈/解决,除非你限制输入的数量/幅度 - 即使是像Java的BigInt(或等C++的等价物,如gmp,NTL等)。
问题很简单:任何计算机的内存都是有限的。我们可以表示的数字总是有一些有限的限制。任意精度整数类型可以增加对数字的限制,远远大于大多数使用常规使用的数字,但无论限制是什么,总会有更大的数字无法表示(至少在不更改为其他表示形式的情况下 - 但是如果我们要对任意数字的单位位置进行精确, 对于我们在表示巨大数字方面的聪明程度,有明显的限制)。
对于链接问题中给出的条件,C 和 C++ 中的long long
类型就足够了。如果我们想通过 C++ 中的解决方案将限制增加到一些荒谬的大小,这很简单。尽管它们不是 C++ 实现的必需部分,但有许多任意精度整数库可用于C++。
我想可能有某种方法可以计算出这个问题的答案,而不涉及实际对数字求和 - 但至少乍一看,这个想法对我来说似乎不是很有希望。问题的陈述专门涉及计算总和。虽然您当然可以进行各种阴谋诡计来防止求和看起来像求和,但事实是问题的基本陈述涉及求和,这往往表明不涉及求和的解决方案可能很难找到。
是的,这是可能的。请注意,如果data[0] < data[len - 1]
,则data[1]
应属于"左"部分;同样,如果data[0] > data[len-1]
那么data[len-2]
属于"正确"部分。这种观察允许归纳证明以下算法的正确性:
left_weight = 0; right_weight = 0
left_index = 0; right_index = 0
while left_index < right_index
if left_weight < right_weight
left_weight += data[left_index++];
else
right_weight += data[--right_index]
仍然有累积,但通过跟踪不平衡和哪一侧较重的布尔指标很容易处理:
while left_index < right_index
if heavier_side == right
weight = data[left_index++]
else
weight = data[--right_index]
if weight < imbalance
imbalance = imbalance - weight
else
heavier_side = !heavier_side
imbalance = weight - imbalance
至少对于未签名的data
没有溢出的可能性。可能需要对有符号值进行一些修改。
- 在C++中使用数组时如何防止堆栈溢出?
- 如何防止缓冲区溢出
- 如果用户输入两个或多个由空格分隔的字符串C++如何防止缓冲区溢出?
- 防止 CRTP 特征码在"pure virtual"调用中堆栈溢出
- 为什么 #include <string> 在这里防止堆栈溢出错误?
- 如何防止无限循环游戏中的堆栈溢出
- C++ 计算编译时常量,同时防止整数常量溢出
- 使用boost::序列化递归图结构时,如何防止堆栈溢出
- C 如何计算复数的绝对值,从而防止溢出
- Ncurses/C/C++:使用 getstr() 并防止溢出(必须有更好的方法来做到这一点)
- 防止用户脚本造成堆栈溢出
- 将字符数组传递给使用构造函数初始化的类构造函数时防止溢出
- 如何防止C中的双重溢出
- 数组大数的均衡指数,如何防止溢出
- 如何防止 sqrt 中的溢出
- 增加堆栈保留大小不会防止堆栈溢出
- 如何在使用常用数学函数exp()log()时防止溢出
- 防止std::atomic溢出
- 使用C或C++时,如何防止整数溢出
- CPP:防止溢出的类型转换