我需要使用mergesort对2个向量(A和B)进行排序,然后将排序后的元素放入第3个向量(R)。
在A中有3个元素(1,3,5)和B为(2,4,6)的测试中,我的代码运行良好,直到必须插入第四个元素。此时,我的代码因向量下标超出范围错误而崩溃。
这是我第一次使用向量,但是我认为push_back()
函数会调整向量的大小。我的直觉是目标向量(R)只能容纳3个元素,因此当我插入第4个元素时,我的代码崩溃了。我需要做一些调整R大小的事情吗?
using namespace std;
#include <iostream>
#include <vector>
// combine two sorted lists A and B into R
// displays comparison every time it is done
void combine(vector<int> A, vector<int> B, vector<int>& R)
{
int ia = 1;
int ib = 1;
int ir = 1;
while (!A.empty() && !B.empty()) {
if (A[ia] < B[ib]) {
R.push_back(A[ia]);
ia++;
ir++;
}
else {
R.push_back(B[ib]);
ib++;
ir++;
}
}
if (!A.empty()) {
for (int i = ia; i < A.size(); i++) {
R.push_back(A[i]);
}
}
else if (!B.empty()) {
for (int i = ib; i < B.size(); i++) {
R.push_back(B[i]);
}
}
cout << "comparison" << endl;
// be careful -- R comes in as an empty vector
}
int main()
{
vector<int> L1;
vector<int> L2;
vector<int> L3;
int N; // how many elements in each of L1 and L2
int e; // for each element
cout << "How many elements in each list?" << endl;
cin >> N;
cout << "List1" << endl;
for (int i = 1; i <= N; i++)
{
cout << "element :"; cin >> e; L1.push_back(e);
}
cout << "List2" << endl;
for (int i = 1; i <= N; i++)
{
cout << "element :"; cin >> e; L2.push_back(e);
}
combine(L1, L2, L3);
cout << "The result is: ";
for (int i = 0; i < N * 2; i++)
{
cout << L3[i];
} cout << endl;
}// end of main
答案 0 :(得分:0)
向量A和B始终不为空,除非pop_front
简单地喜欢,
if(A.at(0) < B.at(0)) {
C.push_back(A.at(0));
A.pop_front();
}
或循环直到A和B的大小
int ia = 0;
int ib = 0;
while(ia < A.size() && ib < B.size())
{
if(A.at(ia) < B.at(ib))
{
C.push_back(A.at(ia));
ia++;
}
// ...
}
答案 1 :(得分:0)
您的观点是正确的:我认为push_back()
函数会调整矢量的大小。
该错误是由于程序中无效的索引访问所致。
在程序中,while
循环的终止条件为while (!A.empty() && !B.empty())
。由于您没有删除向量A
或B
的任何元素,因此终止条件将永远无法满足。这会导致无限循环,并进一步导致访问向量A
或B
中的无效索引(取决于已交叉的ia
或ib
中的向量各个向量的实际大小)。
还请注意以下几点:
if (!A.empty())
和if (!B.empty())
将始终为true
。由于您没有从向量A
和B
中删除元素。 以下是更正的代码。您可以see it working here:
#include <iostream>
#include <vector>
using namespace std;
// combine two sorted lists A and B into R
// displays comparison every time it is done
void combine(vector<int> A, vector<int> B, vector<int>& R)
{
int ia = 0;
int ib = 0;
int sA = A.size();
int sB = B.size();
while ((ia < sA) && (ib < sB)) {
if (A[ia] < B[ib]) {
R.push_back(A[ia]);
ia++;
}
else {
R.push_back(B[ib]);
ib++;
}
}
while(ia < sA)
{
R.push_back(A[ia++]);
}
while(ib < sB)
{
R.push_back(B[ib++]);
}
cout << "comparison" << endl;
// be careful -- R comes in as an empty vector
}
int main()
{
vector<int> L1;
vector<int> L2;
vector<int> L3;
int N; // how many elements in each of L1 and L2
int e; // for each element
cout << "How many elements in each list?" << endl;
cin >> N;
cout << "List1" << endl;
for (int i = 1; i <= N; i++)
{
cout << "element :"; cin >> e; L1.push_back(e);
}
cout << "List2" << endl;
for (int i = 1; i <= N; i++)
{
cout << "element :"; cin >> e; L2.push_back(e);
}
combine(L1, L2, L3);
cout << "The result is: ";
for (int i = 0; i < N * 2; i++)
{
cout << L3[i] << " | ";
} cout << endl;
}// end of main
以下为经过纠正的经过纠正的代码,并使用了iterator
。您可以see it working here:
using namespace std;
#include <iostream>
#include <vector>
// combine two sorted lists A and B into R
// displays comparison every time it is done
void combine(const vector<int>& A, const vector<int>& B, vector<int>& R)
{
auto itA = A.begin();
auto itB = B.begin();
while ( (itA != A.end()) && (itB != B.end()) )
{
if (*itA < *itB)
{
R.push_back(*itA);
itA++;
}
else
{
R.push_back(*itB);
itB++;
}
}
while(itA != A.end())
{
R.push_back(*itA);
itA++;
}
while(itB != B.end())
{
R.push_back(*itB);
itB++;
}
cout << "comparison" << endl;
// be careful -- R comes in as an empty vector
}
int main()
{
vector<int> L1;
vector<int> L2;
vector<int> L3;
int N; // how many elements in each of L1 and L2
int e; // for each element
cout << "How many elements in each list?" << endl;
cin >> N;
cout << "List1" << endl;
for (int i = 0; i < N; i++)
{
cout << "element :"<<endl; cin >> e; L1.push_back(e);
}
cout << endl << "List2" << endl;
for (int i = 0; i < N; i++)
{
cout << "element :"<<endl; cin >> e; L2.push_back(e);
}
combine(L1, L2, L3);
cout << "The result is: ";
for (int i = 0; i < N * 2; i++)
{
cout << L3[i]<<" | ";
}
}// end of main
答案 2 :(得分:-1)
在循环中,您检查向量是否为空,我认为您应该检查它们的计数器是否在范围之内或类似的范围。例如,如果向量A为[1,2],而B为[3,4,5],则在循环两次并插入A向量之后,ia现在将超出范围,但是您仍然可以通过if语句访问A [ia]与B [ib]进行比较,我相信这是向量超出范围的地方。我也相信向量索引从0开始,这也可能是您的问题。