在列表<int>或vector <int>中添加备用数字

时间:2015-07-10 02:59:39

标签: c++ list vector

我尝试访问列表中的备用号码以添加其值。例如,对于如果List的值为{1,2,3,5}。我应该得到输出,4和7。

为此,我使用了std :: List。首先,我需要能够访问序列的第N个元素std::list才能添加值。也就是说,我知道我可以使用std::advance来获取第N个元素的迭代器:

std::list<Object> l;

unsigned N = /* index of the element that I want to retrieve */;
if (l.size() > N)
{
    std::list<Object>::iterator it = l.begin();
    std::advance(it, N);
}

但是,这并不能解决我的问题,因为我不了解如何在添加备用值时访问备用值,因为它不提供随机访问。

所以,我尝试使用我正在使用的std::vector

sum_of_vector =std::accumulate(vector.begin(),vector.end(),0);

当我添加向量的所有值时,这很有效,但如果我只需要添加std::liststd::vector的备用值,我就不会理解逻辑。

5 个答案:

答案 0 :(得分:2)

请参阅以下代码。我添加了评论,以便它不言自明。

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    //Your vector of integers
    vector<int> V = {1, 2, 3, 5};

    //Size of your vector
    int n = V.size();

    //Initialise two integers to hold the final sum
    int sum1 = 0;
    int sum2 = 0;

    //Calculate sum1 starting from first element and jumping alternate element until you reach end
    for(int i=0; i<n; i+=2)
        sum1 += V[i];

    //Calculate sum2 starting from second element and jumping alternate element until you reach end
    for(int i=1; i<n; i+=2)
        sum2 += V[i];

    //Print your answer
    cout << "Sum1 = " << sum1 << " " << "Sum2 = " << sum2 << endl;

    return 0;
}

答案 1 :(得分:1)

这样的事情怎么样:

findstr

答案 2 :(得分:1)

解决方案非常简单。

  1. 创建一个包含两个元素的数组以累积总和。
  2. 使用在01之间交替的索引。
  3. Object sum[2] = {0};
    int index = 0;
    auto iter = l.begin();
    auto end = l.end();
    for ( ; iter != end; ++iter, index = (index+1)%2 )
    {
        sum[index] += *iter;
    }
    

    代码说明,以回应OP的评论

    我们以您的列表为例:

    l is {1, 2, 3, 5}
    

    for循环的开头:

    sum[0] = sum[1] = 0
    index = 0
    iter points to the element whose value is 1
    

    循环执行时,

    sum[index] = sum[0] = 1
    

    在循环的下一次迭代中,

    index = 1
    iter points to the element whose value is 2
    

    循环执行时,

    sum[index] = sum[1] = 2
    

    在循环的下一次迭代中,

    index = 0
    iter points to the element whose value is 3
    

    循环执行时,

    sum[index] = sum[0] = 4
    

    在循环的下一次迭代中,

    index = 1
    iter points to the element whose value is 5
    

    循环执行时,

    sum[index] = sum[1] = 7
    

    在循环的下一次迭代中,     index = 0     它指向结束。循环执行停止。

    此时,

    sum[0] = 4
    sum[1] = 7
    

答案 3 :(得分:1)

递归爱好者可能会建议:

typedef std::list<int>    IntList;
typedef IntList::iterator IntListIT;

void odd (IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend);
void even(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend);


void even(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend) {
   sumEven += *IT;
   if(++IT != ITend)
      odd(IT, sumEven, sumOdd, ITend); // tail-recursion
}

void odd(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend) {
   sumOdd += *IT;
   if(++IT != ITend)
      even(IT, sumEven, sumOdd, ITend); // tail-recursion
}

int t209(void)
{
   IntList   intList;
   for (int i=0; i<10; ++i)
      intList.push_back(i+1);

   int sumEven = 0;
   int sumOdd  = 0;
   even(intList.begin(), sumEven, sumOdd, intList.end());

   std::cout << "\nsumEven: " << sumEven
             << "\n sumOdd: " << sumOdd
             << "\n  total: " << (sumEven + sumOdd)
             << std::endl;

   return(0);
}

带输出

sumEven: 25
 sumOdd: 30
  total: 55

一位不同的递归爱好者不喜欢“凌乱”。 4参数递归函数,可以建议一个类的努力。令人惊讶的是(?或者您怀疑这一点),他能够消除(!)所有(可见)参数,用于类#es 2相互递归方法。

// class Even-Odd-Sum 
class EOSum          // wrap recursive efforts
{
public:
   EOSum(IntList& intList) :
      m_list(intList),
      m_eSum(0),
      m_oSum(0),
      m_IT(intList.begin()),
      m_ITend  (intList.end())
      { }

   ~EOSum() { m_eSum = 0; m_oSum = 0; }

   std::string operator()()
      {
         // do the math
         e();  // recursively

         // report results
         std::stringstream ss;
         ss << "\n  eSum: " << m_eSum
            << "\n  oSum: " << m_oSum
            << "\n total: " << (m_eSum + m_oSum)
            << "\n\n sizeof(this): " << sizeof(this) << " bytes.  "
            << "\nestimated total stack needed with unoptimized recursive call: "
            << DTB::digiComma(C100M*(2*sizeof(this)))
            << "\ndefault stack size Ubuntu 15.04                             :     "
            << DTB::digiComma(8*1024*1024)
            << std::endl;
         return(ss.str());
      }

   static const int C100M = 100000000;

private:
   IntList&  m_list;
   int64_t   m_eSum;
   int64_t   m_oSum;
   IntListIT m_IT;    // iterate thru the list
   IntListIT m_ITend;

   // the new and improved recursion - NO (visible) PARAMETERS
   void e()
      {
         m_eSum += *m_IT;
         if (++m_IT != m_ITend)
            o(); // tail-recursion
      }

   void o()
      {
         m_oSum += *m_IT;
         if (++m_IT != m_ITend)
            e(); // tail-recursion
      }
};

// test 
int t209b(void)
{
   std::cout << "\n\nt209b start: using EOSum::C100M = "
             << DTB::digiComma(EOSum::C100M) << " multiplier  (~10 seconds on lab005)"
             << std::endl;
   uint64_t t209bStartMS = DTB::getSystemMillisecond();

   uint64_t dtorStartMS;
   {
      IntList   intList;

      {
         uint64_t startMS = DTB::getSystemMillisecond();

         for (int i=0;   i<EOSum::C100M; ++i)  // use -O3 to avoid segfault - tail recursion optimized
            intList.push_back(i+1);

         uint64_t durationMS = DTB::getSystemMillisecond() - startMS;
         std::cout << "\n100M list push_back's   : " << durationMS << " ms"
                   << "\n     to 'new' intList elements " << std::endl;
      }

      {
         uint64_t startMS = DTB::getSystemMillisecond();

         // Ubuntu 15.04 default stack size  8 M Bytes
         //     100,000: No stack over flow
         //   1,000,000: -O0 stack overflow segfault, -O3: No segfault
         // 100,000,000: -O3: No segfault
         std::cout << EOSum(intList)() << std::endl;

         uint64_t durationMS = DTB::getSystemMillisecond() - startMS;
         std::cout << "100 M recursion calls   : " << durationMS << " ms "
                   << "\n    to compute eSum, oSum, total shown above " << std::endl;
      }

      dtorStartMS = DTB::getSystemMillisecond();

   }  // intList destruction at this brace

   uint64_t dtorDurationMS = DTB::getSystemMillisecond() - dtorStartMS;
   std::cout << "\n100 M list item dtor's  : " << dtorDurationMS
             << "\n      to 'delete' intList elements " <<  std::endl;


   uint64_t t209bDurationMS = DTB::getSystemMillisecond() - t209bStartMS;

   std::cout << "\n t209b() duration MS    : " << t209bDurationMS << std::endl;

   return(0);
}

在此代码中,当使用优化级别0(-O0)时,堆栈溢出(在递归期间),在列表中添加了100,000到1 M个元素。请注意,Ubuntu 15.04的默认堆栈只有8 M字节,每个方法调用可能使用16个字节(此ptr,并返回addr)。

然而,作者实现了尾递归,并且由于g ++ 4.9.2编译器令人印象深刻的优化(在3级,-O3),这个递归现在使用 fixed 堆栈元素的数量!尽管双相互递归方法增加了复杂性。

此代码有一些个人库使用,所以这里是测试的输出:

随意在您的机器上尝试此操作(使用一些简单的替换或删除我的DTB ::方法)。

所有持续时间都来自我6岁以上的戴尔。

t209b start: using EOSum::C100M = 100,000,000 multiplier (~10 seconds on lab005)

100M list push_back's   : 6930 ms
     to 'new' intList elements 

  eSum: 2500000000000000
  oSum: 2500000050000000
 total: 5000000050000000

 sizeof(this): 8 bytes.  
estimated total stack needed with unoptimized recursive call: 1,600,000,000
default stack size Ubuntu 15.04                             :     8,388,608

100 M recursion calls   : 1320 ms 
    to compute eSum, oSum, total shown above 

100 M list item dtor's  : 2754
      to 'delete' intList elements 

 t209b() duration MS    : 11035


real  0m11.290s
user  0m8.532s
sys   0m2.556s

答案 4 :(得分:0)

这看起来像std::valarray可能合适的情况。假设你的目标是添加所有偶数成员和所有奇数成员,你可以这样做:

std::valarray<int> l;
// Put stuff into the array
std::valarray<int> even = l[std::slice(0, l.size() / 2, 2)]
std::valarray<int> odd  = l[std::slice(1, l.size() / 2, 2)];
int sum_of_odd = odd.sum(), sum_of_even = even.sum();