添加两个不同大小的独立 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());

这将处理任何有效长度的向量。 (我将把寻找可以表示无限长度向量的硬件的问题作为未解决的挑战)。

上面的代码假定 v1v2 的所有元素都在 09 范围内。它可以被简单地修改以处理值 10 或更多的元素。我会把它留作练习。

通过调用 v3.reserve() 将元素推入 v3 时,可以减少内存 allocation/reallocation。我会把它留作练习。

这是我根据所需条件设计的一个简单方法:(考虑向量 v1v2,数据类型 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>());

这会将 v1v2 的 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.