我有一个将两个已排序的向量合并为第三个有序向量的赋值。我确信这个问题的解决方案非常简单,但我的大脑现在已经被炒了,可以使用你的帮助。
基本上,矢量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;
}
}
答案 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循环中想要做什么。但是,如果您只是使用R
和A
中的元素填充向量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现在正在做什么。
将R
初始化为{0,0,0,0,0,0}
直到一个向量的所有值都插入到R
比较候选中并将较小的值插入R
,从获胜者列表中获取下一个候选者。
这就是全部 - 我不知道这是函数的目的,如果你写它我/我们可以提供解决方案,否则只需回顾上述表格中的第二点。
答案 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
方法意味着我将附加到向量。如果忘记向量将扩展以解决分配,则分配路线可能会使读者失控。