【问题标题】:Adding elements to a vector将元素添加到向量
【发布时间】:2019-09-27 19:28:30
【问题描述】:

我需要使用合并排序对 2 个向量(A 和 B)进行排序,并将排序后的元素放入第三个向量 (R)。
在 A (1,3,5) 和 B 为 (2,4,6) 中的 3 个元素的测试中,我的代码运行正常,直到我必须插入第 4 个元素。此时我的代码因向量下标超出范围错误而崩溃。

这是我第一次使用向量,但我认为 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

【问题讨论】:

  • combine 中研究while 循环的条件。循环中是否有任何东西会改变该条件的值?
  • 我建议你做一些rubber duck debuggingcombine 函数。尤其是在第一个循环中。想想AB 什么时候会变空。
  • 记住向量索引是从零开始的。
  • 最后,你确定L3.size() == N * 2吗?为什么不使用L3.size(),它保证是向量的确切大小。

标签: c++ vector stl mergesort


【解决方案1】:

向量 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++;
    }
    // ...
}

【讨论】:

    【解决方案2】:

    你说得对:我认为push_back() 函数会调整向量的大小。

    错误是由于您的程序中的索引访问无效。

    在您的程序中,while 循环的终止条件是 while (!A.empty() &amp;&amp; !B.empty())。由于您没有删除向量 AB 的任何元素,因此终止条件永远不会满足。这会导致无限循环,并进一步导致访问向量AB 中的无效索引(取决于,在iaib 中,它们已经超过了各自向量的实际大小)。

    还要注意以下几点:

    • 您已开始从索引 1 而不是 0 访问元素。向量的索引从 0 开始。
    • 条件if (!A.empty())if (!B.empty()) 将始终为true。由于您没有从向量AB 中删除元素。

    以下是更正的代码。你可以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
    

    【讨论】:

      【解决方案3】:

      在您的循环中,您检查向量是否为空,我认为您应该检查它们的计数器是否在范围内或类似的东西。例如,如果向量 A 是 [1,2] 并且 B 是 [3,4,5] 在循环两次之后插入 A 向量 ia 现在将超出范围,但您仍然可以进入 if 语句,其中 A[ia]与 B[ib] 相比,我相信这是您超出向量范围的地方。另外我相信向量索引从 0 开始,这也可能是你的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-18
        • 2018-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-02
        相关资源
        最近更新 更多