如何将 std::vector<int> 乘以 int,其中向量的每个元素应为一位数?
How to multiply std::vector<int> by int where vector's each element should be one digit?
我有一个 class,称之为 'BigNumber',它有一个矢量 v 场。
每个元素应该是一个数字。
我想实现一种方法,将此向量乘以一个整数,但也将元素保留一位。
例如:<7,6> * 50 = <3,8,0,0>
向量表示一个数字,以这种方式存储。
在我的示例中,<7,6> 等于 76,<3,8,0,0> 等于 3800。
我尝试了以下方法,但这不是很好(但它有效),而不是问题的实际解决方案。
//int num, BigNumber bn
if (num > 0)
{
int value = 0, curr = 1;
for (int i = bn.getBigNumber().size() - 1; i >= 0; i--)
{
value += bn.getBigNumber().at(i) * num * curr;
curr *= 10;
}
bn.setBigNumber(value); //this shouldn't be here
return bn;
}
预期的算法是将向量本身相乘,而不是与我转换为该 BigNumber 的变量相乘。
我将 Integer 设置为 BigNumber 的方式:
void BigNumber::setBigNumber(int num)
{
if (num > 0)
{
bigNum.clear();
while (num != 0)
{
bigNum.push_back(num % 10);
num = (num - (num % 10)) / 10;
}
std::reverse(bigNum.begin(), bigNum.end());
}
else
{
throw TOOSMALL;
}
};
我要实现的方法:
//class BigNumber{private: vector<int> bigNum; ... }
void BigNumber::multiplyBigNumber(BigNumber bn, int num)
{
if (num > 0)
{
//bn.bigNum * num
}
else
{
throw TOOSMALL;
}
}
由于这是一个学校项目,我不想只为您编写代码。所以这里有一个提示。
假设您给我数字 1234 --- 我选择将每个数字存储在向量中 反向 。所以现在我有 bignum = [4, 3, 2, 1].
现在你要我把它乘以 5。所以我创建了一个新的空向量 result=[ ]。我查看 bignum 中的第一项。这是一个 4.
4 * 5 是 20,或者(就像你在学校做的那样)它是 0 进位 2。所以我将 0 推入结果,给出结果 = [0] 和进位 = 2。
你的问题:
- 如果您手动(在纸上)这样做,接下来您会做什么?
- 为什么我决定以相反的顺序存储数字?
- 为什么我决定使用新向量(结果)而不是修改 bignum?
并且只有在您弄清楚如何将 bignum 乘以 int 之后:
- 如何将两个大数相乘?
问题的解决方案是下面的代码。我不知道我是否可以让这个算法更快,但它有效,所以我很满意。
BigNumber BigNumber::multiplyBigNumber(BigNumber bn, int num){
if (num > 0)
{
std::vector<int> result;
std::vector<int> rev = bn.getBigNumber();
std::reverse(rev.begin(),rev.end());
int carry = 0;
for(int i = 0; i<rev.size(); i++){
result.push_back((rev[i] * num + carry) % 10);
carry = (rev[i] * num + carry) / 10;
if(i == rev.size()-1 && carry / 10 == 0 && carry % 10 != 0 ) {
result.push_back(carry);
carry = carry / 10;
}
}
while((carry / 10) != 0){
result.push_back(carry % 10);
carry /= 10;
if(carry / 10 == 0) result.push_back(carry);
}
std::reverse(result.begin(),result.end());
bn.setBigNumber(result);
return bn;
}else{
throw TOOSMALL;
}
}
我有一个 class,称之为 'BigNumber',它有一个矢量 v 场。
每个元素应该是一个数字。
我想实现一种方法,将此向量乘以一个整数,但也将元素保留一位。
例如:<7,6> * 50 = <3,8,0,0>
向量表示一个数字,以这种方式存储。
在我的示例中,<7,6> 等于 76,<3,8,0,0> 等于 3800。
我尝试了以下方法,但这不是很好(但它有效),而不是问题的实际解决方案。
//int num, BigNumber bn
if (num > 0)
{
int value = 0, curr = 1;
for (int i = bn.getBigNumber().size() - 1; i >= 0; i--)
{
value += bn.getBigNumber().at(i) * num * curr;
curr *= 10;
}
bn.setBigNumber(value); //this shouldn't be here
return bn;
}
预期的算法是将向量本身相乘,而不是与我转换为该 BigNumber 的变量相乘。
我将 Integer 设置为 BigNumber 的方式:
void BigNumber::setBigNumber(int num)
{
if (num > 0)
{
bigNum.clear();
while (num != 0)
{
bigNum.push_back(num % 10);
num = (num - (num % 10)) / 10;
}
std::reverse(bigNum.begin(), bigNum.end());
}
else
{
throw TOOSMALL;
}
};
我要实现的方法:
//class BigNumber{private: vector<int> bigNum; ... }
void BigNumber::multiplyBigNumber(BigNumber bn, int num)
{
if (num > 0)
{
//bn.bigNum * num
}
else
{
throw TOOSMALL;
}
}
由于这是一个学校项目,我不想只为您编写代码。所以这里有一个提示。
假设您给我数字 1234 --- 我选择将每个数字存储在向量中 反向 。所以现在我有 bignum = [4, 3, 2, 1].
现在你要我把它乘以 5。所以我创建了一个新的空向量 result=[ ]。我查看 bignum 中的第一项。这是一个 4.
4 * 5 是 20,或者(就像你在学校做的那样)它是 0 进位 2。所以我将 0 推入结果,给出结果 = [0] 和进位 = 2。
你的问题:
- 如果您手动(在纸上)这样做,接下来您会做什么?
- 为什么我决定以相反的顺序存储数字?
- 为什么我决定使用新向量(结果)而不是修改 bignum?
并且只有在您弄清楚如何将 bignum 乘以 int 之后:
- 如何将两个大数相乘?
问题的解决方案是下面的代码。我不知道我是否可以让这个算法更快,但它有效,所以我很满意。
BigNumber BigNumber::multiplyBigNumber(BigNumber bn, int num){
if (num > 0)
{
std::vector<int> result;
std::vector<int> rev = bn.getBigNumber();
std::reverse(rev.begin(),rev.end());
int carry = 0;
for(int i = 0; i<rev.size(); i++){
result.push_back((rev[i] * num + carry) % 10);
carry = (rev[i] * num + carry) / 10;
if(i == rev.size()-1 && carry / 10 == 0 && carry % 10 != 0 ) {
result.push_back(carry);
carry = carry / 10;
}
}
while((carry / 10) != 0){
result.push_back(carry % 10);
carry /= 10;
if(carry / 10 == 0) result.push_back(carry);
}
std::reverse(result.begin(),result.end());
bn.setBigNumber(result);
return bn;
}else{
throw TOOSMALL;
}
}