添加两个不同大小的独立 int 向量的值?
Adding values of two separate int vectors with different sizes?
我想知道如何将两个向量的值相加,如下所示:
vector<int> v1 = {3, 1, 7};
vector<int> v2 = {6, 5};
vector<int> v3 = {3, 8, 2}; // The sum of v1 and v2
这里的结果应该是 382,因为 317 + 65 得到 382。
有办法吗?矢量的大小非常棘手。比如v1中的第2个元素是1,但是v2中的第2个元素是5。但是7必须加上5,而不是1。
编辑: 忘了说向量可以无限长。强制转换为 int 然后返回 vector 可能会导致数字丢失。
你想要这样的东西吗?:
此代码首先将 v1、v2 向量转换为整数 n1、n2
并做整数和加起来为n3。
然后再将整数n3转化为向量
vector<int> v1 = {3, 1, 7};
vector<int> v2 = {6, 5};
vector<int> v3;// = {3, 8, 2}; // The sum of v1 and v2
int n1=0; for(int a:v1) n1=10*n1+a;
int n2=0; for(int a:v2) n2=10*n2+a;
int n3 = n1 + n2;
while(n3) v3.insert(v3.begin(), n3%10),n3/=10;
//now v3 = {3, 8, 2}
简单的方法是反向迭代向量。
std::vector<int>::const_reverse_iterator first = v1.rbegin(), endfirst = v1.rend();
std::vector<int>::const_reverse_iterator second = v2.rbegin(), endsecond = v2.rend();
// if adding two digits gives a value of 10 or more, need to carry
int carry = 0;
std::vector<int> v3(0);
// first do summations of digits in reverse until one vector has no more
// the following loops will collect digits in v3 (the notional "sum" of v1 and v2)
// in reverse order
while (first != endfirst && second != endsecond)
{
int sum = *first + *second + carry;
carry = (sum >= 10) ? 1 : 0;
v3.push_back(sum % 10);
++first; ++second;
}
// if we have reached the end of v1, there may be additional elements in v2, so
if (first == firstend)
{
first = second;
firstend = secondend;
}
// first and firstend specify the range in whichever vector (v1 or v2) has
// more elements
// The next loop does nothing if v1 and v2 have the same length
while (first != firstend)
{
int sum = *first + carry;
carry = (sum >= 10) ? 1 : 0;
v3.push_back(sum % 10);
++first;
}
// if we are carrying a digit after doing all the sums, then push a 1
if (carry) v3.push_back(1);
// we have pushed the digits into v3 in reverse order, so ....
std::reverse(v3.begin(), v3.end());
这将处理任何有效长度的向量。 (我将把寻找可以表示无限长度向量的硬件的问题作为未解决的挑战)。
上面的代码假定 v1
和 v2
的所有元素都在 0
到 9
范围内。它可以被简单地修改以处理值 10
或更多的元素。我会把它留作练习。
通过调用 v3.reserve()
将元素推入 v3
时,可以减少内存 allocation/reallocation。我会把它留作练习。
这是我根据所需条件设计的一个简单方法:(考虑向量 v1
和 v2
,数据类型 DT
)
- 大小差异: 对于向量大小不等的情况,您可以通过使用迭代器使用
std::vector<>::insert(iterator, 0)
简单地在末尾附加 0
设置为开头,因为您需要首先使用零才能正确添加 element-to-element。不过在此之前,先检查两个向量中哪个向量的大小更大,然后收集差异并在循环中插入相同的次数:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
- 加法: 现在矢量大小相等,您可以使用
functional
header 中的 std::plus
添加元素一个向量(比如 v1
)到另一个向量(v2
)element-wise,在 std::transform
: 中放置适当的迭代器位置
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), std::plus<DT>());
这会将 v1
和 v2
的 element-wise 总和收集到 v1
(可互换)。唯一需要处理的问题或条件是 element-wise 加法总和大于或等于 10 的情况下的溢出。
- 溢出: 对于向量中除第一个元素之外的所有元素(在第 0th 索引处),我们需要carry/add
1
到溢出的情况下的下一个元素 (>=10
) 并将当前向量元素分配给除以 10 时的余数。但是,对于第一个溢出的元素,我们'您需要将另一个元素分配给向量的开头(例如:{3, 1} + {9, 2} = {1, 2, 3}),这将再次是 1
(考虑单个数字向量元素),我们可以对其施加单独的 if
语句:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7, 8};
std::vector<DT> v2 = {4, 5, 6};
// 52578
// 00456
// -----
// Expected output: // 53034
// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());
// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i - 1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
// Display the sum:
for(auto v:v1)
std::cout << v;
}
输出:53034
.
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7};
std::vector<DT> v2 = {9, 3, 7, 2};
// 5257
// 9372
// -----
// Expected output: // 14629
// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());
// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
// Display the sum:
for(auto v:v1)
std::cout << v;
}
输出:14629
.
我想知道如何将两个向量的值相加,如下所示:
vector<int> v1 = {3, 1, 7};
vector<int> v2 = {6, 5};
vector<int> v3 = {3, 8, 2}; // The sum of v1 and v2
这里的结果应该是 382,因为 317 + 65 得到 382。
有办法吗?矢量的大小非常棘手。比如v1中的第2个元素是1,但是v2中的第2个元素是5。但是7必须加上5,而不是1。
编辑: 忘了说向量可以无限长。强制转换为 int 然后返回 vector 可能会导致数字丢失。
你想要这样的东西吗?:
此代码首先将 v1、v2 向量转换为整数 n1、n2
并做整数和加起来为n3。
然后再将整数n3转化为向量
vector<int> v1 = {3, 1, 7};
vector<int> v2 = {6, 5};
vector<int> v3;// = {3, 8, 2}; // The sum of v1 and v2
int n1=0; for(int a:v1) n1=10*n1+a;
int n2=0; for(int a:v2) n2=10*n2+a;
int n3 = n1 + n2;
while(n3) v3.insert(v3.begin(), n3%10),n3/=10;
//now v3 = {3, 8, 2}
简单的方法是反向迭代向量。
std::vector<int>::const_reverse_iterator first = v1.rbegin(), endfirst = v1.rend();
std::vector<int>::const_reverse_iterator second = v2.rbegin(), endsecond = v2.rend();
// if adding two digits gives a value of 10 or more, need to carry
int carry = 0;
std::vector<int> v3(0);
// first do summations of digits in reverse until one vector has no more
// the following loops will collect digits in v3 (the notional "sum" of v1 and v2)
// in reverse order
while (first != endfirst && second != endsecond)
{
int sum = *first + *second + carry;
carry = (sum >= 10) ? 1 : 0;
v3.push_back(sum % 10);
++first; ++second;
}
// if we have reached the end of v1, there may be additional elements in v2, so
if (first == firstend)
{
first = second;
firstend = secondend;
}
// first and firstend specify the range in whichever vector (v1 or v2) has
// more elements
// The next loop does nothing if v1 and v2 have the same length
while (first != firstend)
{
int sum = *first + carry;
carry = (sum >= 10) ? 1 : 0;
v3.push_back(sum % 10);
++first;
}
// if we are carrying a digit after doing all the sums, then push a 1
if (carry) v3.push_back(1);
// we have pushed the digits into v3 in reverse order, so ....
std::reverse(v3.begin(), v3.end());
这将处理任何有效长度的向量。 (我将把寻找可以表示无限长度向量的硬件的问题作为未解决的挑战)。
上面的代码假定 v1
和 v2
的所有元素都在 0
到 9
范围内。它可以被简单地修改以处理值 10
或更多的元素。我会把它留作练习。
通过调用 v3.reserve()
将元素推入 v3
时,可以减少内存 allocation/reallocation。我会把它留作练习。
这是我根据所需条件设计的一个简单方法:(考虑向量 v1
和 v2
,数据类型 DT
)
- 大小差异: 对于向量大小不等的情况,您可以通过使用迭代器使用
std::vector<>::insert(iterator, 0)
简单地在末尾附加0
设置为开头,因为您需要首先使用零才能正确添加 element-to-element。不过在此之前,先检查两个向量中哪个向量的大小更大,然后收集差异并在循环中插入相同的次数:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
- 加法: 现在矢量大小相等,您可以使用
functional
header 中的std::plus
添加元素一个向量(比如v1
)到另一个向量(v2
)element-wise,在std::transform
: 中放置适当的迭代器位置
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), std::plus<DT>());
这会将 v1
和 v2
的 element-wise 总和收集到 v1
(可互换)。唯一需要处理的问题或条件是 element-wise 加法总和大于或等于 10 的情况下的溢出。
- 溢出: 对于向量中除第一个元素之外的所有元素(在第 0th 索引处),我们需要carry/add
1
到溢出的情况下的下一个元素 (>=10
) 并将当前向量元素分配给除以 10 时的余数。但是,对于第一个溢出的元素,我们'您需要将另一个元素分配给向量的开头(例如:{3, 1} + {9, 2} = {1, 2, 3}),这将再次是1
(考虑单个数字向量元素),我们可以对其施加单独的if
语句:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7, 8};
std::vector<DT> v2 = {4, 5, 6};
// 52578
// 00456
// -----
// Expected output: // 53034
// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());
// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i - 1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
// Display the sum:
for(auto v:v1)
std::cout << v;
}
输出:53034
.
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#define DT long long int
int main()
{
std::vector<DT> v1 = {5, 2, 5, 7};
std::vector<DT> v2 = {9, 3, 7, 2};
// 5257
// 9372
// -----
// Expected output: // 14629
// Size management:
int diff;
if(v1.size() > v2.size())
{ diff = v1.size() - v2.size();
for(int i = 0; i < diff; ++i)
v2.insert(v2.begin(), 0);
}
else
{ diff = v2.size() - v1.size();
for(int i = 0; i < diff; ++i)
v1.insert(v1.begin(), 0);
}
// Element-wise addition:
std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(),std::plus<DT>());
// Overflow management:
for(int i = v1.size(); i > 0; --i)
{
if(i == 1 && v1[1] >= 10)
{ v1[1] %= 10;
v1.insert(v1.begin(), 1);
}
else if(i != 1 && v1[i-1] >= 10)
{ v1[i - 1] %= 10;
v1[i - 2] += 1;
}
}
// Display the sum:
for(auto v:v1)
std::cout << v;
}
输出:14629
.