简体   繁体   中英

loop never end ??~ need help. C++

Quesition:

Given input like this:

int myintsA[]={1,3,3,2,2,5,5,5,4};
int myintsB[]={0,9,8,6,7,3,3,4};

Find same elements, out put it. When they appear both 2 times. out put it as 2 times.

For example:
Output: {3,3,4}

   #include <iostream>
#include <vector>
#include <list>
#include <ext/hash_map>

using namespace __gnu_cxx;
using namespace std;

list<int> findDup(const vector<int>& A ,const vector<int>& B)
{
    list<int> idx;
    std::vector<int>::size_type i = 0;
    std::vector<int>::size_type j = 0;
    while(i < A.size() && j < B.size()) {
        if (A[i] == B[j])
        {
            idx.push_back(A[i]);
            i++;
            j++;
        }
        else if(A[i] < B[j])
        {
            i++;
        }
        else if (A[i] > B[j])
        {
            j++;
        }
    }
    return idx;

}

int main()
{
    int myintsA[]={1,3,2,2,5,5,5,4};
    int myintsB[]={0,9,8,6,7,3,3,4};

    vector<int> myvectorA (myintsA, myintsA + sizeof(myintsA) / sizeof(int) );
    vector<int> myvectorB (myintsB, myintsB + sizeof(myintsB) / sizeof(int) );


    sort(myvectorA.begin(),myvectorA.end());
    sort(myvectorB.begin(),myvectorB.end());

    list<int> result = findDup(myvectorA, myvectorB);
    for(list<int>::iterator iter = result.begin(); iter!=result.end();++iter)
    {
        printf("%c",*iter);
    }
    return 0;
}

But my program seems wrong. need help! THank you!

The findDup function has a boundary condition error: what if one of i or j is at the end, but the other isn't? Your loop will continue, accessing beyond the end of the vector. For what you are doing, you should just be able to change the loop condition to (i != A.size()) && (j != B.size()) (changing || to && ).

Another issue is that the %c format is for characters; %d is for int s, and there will be strange results on your terminal if you use %c . You should also print (assuming you want the format you show in the question) a left brace at the beginning of the output list, commas between output numbers, and a right-brace and newline at the end.

@Tim's answer is also correct; you have that typo in your code as well.

    else if(A[i] < B[i])

I assume you meant:

    else if(A[i] < B[j])  // B uses j, not i

that could be the cause of your infinite loop.

Edit: And as Jeremiah points out, your while condition is messed up. Normal practice looks more like this:

while(i < A.size() && j < B.size()) {

Here's a working version of the code posted from earlier:

#include <iostream>
#include <vector>
#include <list>
#include <algorithm> //It's better to use the standard <algorithm> header here for sort.
                     //using <ext/hash_map> just for the sort functionality is not a great idea because it makes the code less clear and also creates portability issues.
using namespace __gnu_cxx;
using namespace std;

list<int> findDup(const vector<int>& A ,const vector<int>& B)
{
    list<int> idx;
    std::vector<int>::size_type i = 0;
    std::vector<int>::size_type j = 0;
    while(i < A.size() && j < B.size()) { //as pointed out before this is the source of the error
        if (A.at(i) == B.at(j)) 
        //using the .at(i) will throw an exception if anything goes out of range of the container. 
        //Operator [] doesn't provide this safety.
        {
            idx.push_back(A.at(i));
            i++;
            j++;
        }
        else if(A.at(i) < B.at(j))
        {
            i++;
        }
        else if (A.at(i) > B.at(j))
        {
            j++;
        }
    }

    return idx; 
    //you didn't actually return anything before

}

int main()
{
    int myintsA[]={1,3,3,2,2,5,5,5,4};
    int myintsB[]={0,9,8,6,7,3,3,4};

    vector<int> myvectorA (myintsA, myintsA + sizeof(myintsA) / sizeof(int) );
    vector<int> myvectorB (myintsB, myintsB + sizeof(myintsB) / sizeof(int) );


    sort(myvectorA.begin(),myvectorA.end());
    sort(myvectorB.begin(),myvectorB.end());

    list<int> result = findDup(myvectorA, myvectorB);
    for(list<int>::iterator iter = result.begin(); iter!=result.end();++iter)
    {
        cout<< *iter ; 
        //using cout is generally safer and more idiomatic c++
    }
            cout << endl;

    return 0;
}

The main issue is the edge case that happens at the end. A few things to note: If you used the .at(i) syntax you would have got a std::out_of_range thrown which would have pointed you in the right direction to finding the problem. Also if you compiled with -Wall you would have been warned about the first function not returning anything.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM