而循环错误

时间:2011-02-17 11:59:42

标签: c++ while-loop

我有一个将两个已排序的向量合并为第三个有序向量的赋值。我确信这个问题的解决方案非常简单,但我的大脑现在已经被炒了,可以使用你的帮助。

基本上,矢量A和B的大小为3.它们将分别保持整数,如1,2,3和4,5,6。我似乎无法正确获取while循环的语法。我试过把它做成do / while循环,在括号内加上括号,以及其他一些东西。它似乎并没有在&&。

之后读取该部分

第一个for循环只是使R向量具有正确的大小。第二个for循环只显示R向量的值。结果应该从1-6打印出来,但我只看到1-3。

任何帮助将不胜感激!

void::combine(vector<int> A, vector<int> B, vector<int> R) {
int ia = 0, ib = 0, ir = 0;

for (int i = 0; i < A.size() + B.size(); i++) {
    R.push_back(0);
}

while (ia != A.size() && ib != B.size()) {
        if (A[ia] < B[ib]) {
             R[ir] = A[ia];
             ia += 1;
        }
        else {
            R[ir] = B[ib];
            ib += 1;
        }
        ir += 1;
}

for (int i = 0; i < R.size(); i++) {
    cout << "L3[" << i << "] = " << R[i] << endl;
}

}

7 个答案:

答案 0 :(得分:1)

假设A包含[1,2,3]而B包含[4,5,6],如你所说,这不会将B向量中的任何元素添加到R向量中。

这是因为在第4次迭代时,ia == 3,所以联合条件不再成立..

尝试将其更改为while(ia != A.size() || ib != B.size())

答案 1 :(得分:1)

可能你应该完全避免循环:

void combine(vector<int> const& A, vector<int> const& B, vector<int> & R) {
   R.resize( A.size() + B.size() );
   std::copy( A.begin(), A.end(), R.begin() );
   std::copy( B.begin(), B.end(), R.begin()+A.size() );
   std::sort( R.begin(), R.end() );
   for ( int i = 0; i < R.size(); ++i )
   {
    cout << "L3[" << i << "] = " << R[i] << endl;
   }
}

当你第一次复制然后订购时,这是次优的,但是对于小尺寸它将没有任何影响。

关于代码的实际问题:尽量避免按值传递,使用resize而不是多个push_back()来修复大小(请注意,如果函数的R参数是a非空向量然后最终大小将比你想要的大)。考虑使用返回值而不是引用参数--easier来读取。您循环直到第一个计数器到达结尾,但将其余元素留在另一个容器中而不进行复制。

使用迭代器的手动实现也会更简单:

typedef std::vector<int> vector_t;
vector_t combine( vector_t const & a, vector_t const & b ) {
   vector_t r( a.size() + b.size() ); // [*]
   vector_t::const_iterator ita = a.begin(), enda = a.end();
   vector_t::const_iterator itb = b.begin(), endb = b.end();
   vector_t::iterator itr = r.begin();

   while ( ita != enda && itb != endb ) {
      if ( *ita < *itb )
         *itr++ = *ita++;
      else 
         *itr++ = *itb++;
   }
   if ( ita != enda ) 
      std::copy( ita, enda, itr );
   else 
      std::copy( itb, endb, itr );

   return r;
}

答案 2 :(得分:1)

我不知道你在while循环中想要做什么。但是,如果您只是使用RA中的元素填充向量B,而不考虑它们的添加顺序,那么您可以使用{{1功能,如:

insert

如果您想订购向量void::combine(const vector<int> &A, const vector<int> &B, vector<int>& R) { R.insert(R.end(), A.begin(), A.end()); R.insert(R.end(), B.begin(), B.end()); } ,那么您可以将以下行添加到上述函数中:

R

如果你这样做,你必须 sort( R.begin(), R.end()); //sorts in increasing order. 。如果要按降序排序,请执行以下操作:

#include<algorithm>

答案 3 :(得分:0)

那是因为你的&&条件。只要ia == A.size(),条件(ia != A.size())的第一部分将始终求值为false,并且循环的ib部分将不会执行。

要修复它,您可以将条件更改为:(iA < A.size()) || (iB < B.size())

答案 4 :(得分:0)

语法很好(否则代码不会编译),但是你的循环条件不是。根据您的示例A = { 1, 2, 3 }B = { 4, 5, 6 },循环将进入A[ia] < B[ib]分支三次,并将ia增加到3.一旦发生这种情况,循环条件的第一部分, ia != A.size()不会是真的,因此循环结束。

由于您已经知道需要在结果向量中放置多少项,因此我建议您使用同一正文的简单while替换for循环。

答案 5 :(得分:0)

e.g。 123和456现在正在做什么。

  1. R初始化为{0,0,0,0,0,0}

  2. 直到一个向量的所有值都插入到R比较候选中并将较小的值插入R,从获胜者列表中获取下一个候选者。

  3. 这就是全部 - 我不知道这是函数的目的,如果你写它我/我们可以提供解决方案,否则只需回顾上述表格中的第二点。

答案 6 :(得分:0)

首先,这有点像经典的合并排序或它的一部分:
http://en.wikipedia.org/wiki/Merge_sort

目标是检查第一个向量A的元素到向量B的元素,并按顺序将元素附加到结果向量R.

因此如果A[i]&lt; B[j],将A[i]追加到R。使用std::vector时,无需在启动前使用零加载结果向量。请参阅std::vector::push_back()

以下是未经测试的代码:

void Sort_Vector(const std::vector& A, const std::vector& B, std::vector& result)
{
  unsigned int index_a = 0;  // Point to first element in first vector.
  unsigned int index_b = 0;  // Point to first element in second vector.
  result.clear();            // Clear all elements, so size == 0.

  while ((index_a < A.size()) && (index_b < B.size())
  {
     if (A[index_a] < B[index_b])
     {
         result.push_back(A[index_a]);
         ++index_a;
     }
     else // B[index_b] <= A[index_a]
     {
         result.push_back(B[index_b]);
         ++index;
     }
  }

  // Append any remaining elements to the result vector.
  // Only one of the two loops should be executed,
  //    the other will fail the comparison expression
  //    and not execute.
  for (; index_a < A.size(); ++index_a)
  {
     result.push_back(A[index_a]);
  }
  for (; index_b < B.size(); ++index_b)
  {
     result.push_back(B[index_b]);
  }
  return;
}

注意我的函数签名(参数)和你的签名(参数)之间的区别。我将源向量作为常量数据传递,结果向量通过引用传递,这使我的函数能够修改调用者的结果向量。

另外,我很懒,使用std::vector::push_back()方法。我相信这比分配给结果向量中的元素更具可读性。 push_back方法意味着我将附加到向量。如果忘记向量将扩展以解决分配,则分配路线可能会使读者失控。