【问题标题】:Adding vectors of doubles of differing sizes in C++在 C++ 中添加不同大小的双精度向量
【发布时间】:2010-08-31 15:18:21
【问题描述】:

我有许多不同大小的向量容器,每个容器都包含双精度数。 我想添加每个向量的元素以创建一个向量 双打。这个简单的例子将举例说明我在说什么:

考虑两个向量 A 有三个元素 3.0 2.0 1.0 和 B 有两个元素 2.0 1.0。我想从最后一个元素开始添加两个向量并工作 向后。这将给出一个包含条目 3.0 4.0 2.0 的数组 C。

最优雅/最有效的方法是什么?

谢谢!

【问题讨论】:

  • 在某些语言中有一个很棒的功能叫做迭代...

标签: c++ vector


【解决方案1】:

一旦你知道你有一个比另一个更大的向量

std::vector<double> new_vector = bigger_vector; // Copy the largest
std::transform(smaller_vector.rbegin(), smaller_vector.rend(), // iterate over the complete smaller vector 
    bigger_vector.rbegin(), // 2nd input is the corresponding entries of the larger vector  
    new_vector.rbegin(),    // Output is the new vector 
    std::plus<double>());   // Add em

这很好,因为您不必执行任何循环缩进,并且适用于任何支持反向迭代器的序列容器。

【讨论】:

    【解决方案2】:

    用迭代器试试这个:

    #include <vector>
    
    void add(
            std::vector<double>& result,
            const std::vector<double>& a,
            const std::vector<double>& b)
    {
        std::vector<double>::const_reverse_iterator sit;
        std::vector<double>::const_reverse_iterator send;
    
        // copy the larger vector
        if (a.size() > b.size() ) {
            result = a;
            sit  = b.rbegin();
            send = b.rend();
        }
        else {
            result = b;
            sit  = a.rbegin();
            send = a.rend();
        }
    
        // add the smaller one, starting from the back
        for (std::vector<double>::reverse_iterator it = result.rbegin();
                sit != send;
                ++it, ++sit)
        {
            *it += *sit;
        }
    }
    

    【讨论】:

      【解决方案3】:

      将较大的向量复制到 C 中,然后将较小的元素与 C 的关联元素相加 (+=)。

      类似:

      std::vector<double> add(const std::vector<double>& a,
                              const std::vector<double>& b)
      {
          std::vector<double> c( (a.size() > b.size()) ? a : b );
          const std::vector<double>& aux = (a.size() > b.size() ? b : a);
          size_t diff = c.size() - aux.size();
      
          for (size_t i = diff; i < c.size(); ++i)
              c[i] += aux[i-diff];
      
          return c;
      }
      

      编辑基于下面反对使用 [] 与迭代器的评论。

      我个人觉得迭代器对于这样的事情过于冗长,但如果你更喜欢它们,那么你可以尝试如下:

      std::vector<double> add(const std::vector<double>& a, 
                              const std::vector<double>& b)
      {
          std::vector<double> c( (a.size() > b.size()) ? a : b);
          std::vector<double>::reverse_iterator c_i;
      
          const std::vector<double>& aux = (a.size() > b.size()) ? b : a;
          std::vector<double>::const_reverse_iterator aux_i;
      
          for (c_i=c.rbegin(), aux_i=aux.rbegin(); aux_i!=aux.rend(); ++c_i, ++aux_i)
              *c_i += *aux_i;
      
          return c;
      }
      

      我没有测试或编译其中任何一个,但我想你明白了。

      【讨论】:

      • 此外,如果此操作对您的特定域有意义并且您在任何地方都使用它,则重载 operator+ 并执行定义中的 andand 操作。
      • 这不会颠倒输入的顺序。也不喜欢使用 [] 而不是迭代器。
      • @Steve Townsend:OP 不想颠倒输入的顺序。至于 [] 与迭代器,我是在 Fortran、Pascal 和 C 上长大的,发现迭代器对于像这样的简单事情过于冗长......但我已经为那些对这些事情感兴趣的人进行了更新。
      • OP 的问题指出“我想从最后一个元素开始添加两个向量并向后工作”。迭代器的使用可能很冗长,但它比 [] 更有效且更具表现力。我们得到指针加法(或减法,因为我们要向后移动)而不是乘法以通过索引访问。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多