我为包含最多10^5
个十进制数字的大无符号整数编写了一个C ++类,它内部有一个BASE = 10^9
和std::vector<long long>
来存储实际数字 -
例如754564575693573452
存储为
std::vector<long long> number = {693573452, 754564575}
在构造函数中,我调整此向量的大小以始终包含一些固定数量的long long
数字,例如它的10 ^ 5,因此单个添加两个大的uint可以有多达10 ^ 6位数(在9 * 10^6
数字系统中是BASE = 10^1
个数字,并且类似于乘法......
因此所有算术运算的速度都提高了9倍,但这只是针对大数字的一些计算而注意到的,对于有大量计算的情况,性能会降低,这是因为类设计,我的构造函数和默认构造函数总是调用resize函数,如前所述,这是线性时间例程。
void Big_uint::read_num_str(const std::string& num_str)
{
// reading from num_str to number
}
Big_uint::Big_uint(const std::string& num_str = "0")
{
number.resize( 1000000 );
read_num_str(num_str);
}
Big_uint::Big_uint(const long long& num)
{
number.resize( 1000000 );
char buff[ 20 ];
_itoa_s(static_cast<int>(num), buff, 10);
std::string s = buff;
read_num_str(s);
}
并且所有算术运算都以这种方式实现
Big_uint operator + (const Big_uint& left, const Big_uint& right)
{
Big_uint res; // resize() called here to initialize a vector
// add algorithm
return res;
}
Big_uint operator * (const Big_uint& left, const Big_uint& right)
{
Big_uint res; // resize() called here to initialize a vector
// some multiplication algorithm here (currently only naive O(n^2) implemented)
return res;
}
因此,它们效率低下。
如何根据运算符重载的输入初始化向量?
我不想将运算符重载更改为add, mul, div
之类的成员函数,并将它们传递给3个参数,其中第3个参数为res
- 预先分配的零初始化Big_uint
为存储二进制运算的结果。
答案 0 :(得分:3)
您不应该以这种方式预先分配存储空间。根本不要预先分配。在每次操作中,您都知道(大约)结果的大小。对于添加,它是输入大小加上一个的最大值。对于mul,它是输入大小的总和。始终尝试仅分配必要的空间来容纳数字。
因此,默认构造函数根本不应该分配。每个其他构造函数都应该检查输入的大小,并分配必要的空间。操作员应(保守地)估计必要的空间,并相应地进行分配。
旁注:您应该使用base 2 ^ 32而不是10 ^ 9(或64位计算机上的2 ^ 64):它的内存消耗略少,性能会更好。
附注2:sizeof(long long)通常是8,所以如果只存储小于10 ^ 9的数字,就会浪费内存。