循环永远不会结束??〜需要帮助。 C ++

时间:2011-02-27 05:53:14

标签: c++ algorithm

Quesition:

给出这样的输入:

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

找出相同的元素,把它拿出来。当它们出现2次时。把它作为2次。

例如:
输出:       {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;
}

但我的节目似乎错了。需要帮忙! 谢谢你!

3 个答案:

答案 0 :(得分:2)

findDup函数有一个边界条件错误:如果ij中的一个结尾,但另一个不是?你的循环将继续,访问超出向量的末尾。对于您正在做的事情,您应该能够将循环条件更改为(i != A.size()) && (j != B.size())(将||更改为&&)。

另一个问题是%c格式适用于字符; %d用于int,如果您使用%c,终端上会有奇怪的结果。您还应该打印(假设您需要在问题中显示的格式)输出列表开头的左括号,输出数字之间的逗号,以及最后的右括号和换行符。

@Tim的回答也是正确的;你的代码中也有这个错字。

答案 1 :(得分:2)

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

我认为你的意思是:

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

这可能是你无限循环的原因。

编辑:正如耶利米指出的那样,你的状况已经搞砸了。正常练习看起来更像是这样:

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

答案 2 :(得分:2)

这是从前面发布的代码的工作版本:

#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;
}

主要问题是最后发生的边缘情况。 有几点需要注意: 如果您使用了.at(i)语法,那么您将获得一个std :: out_of_range,它会指向您找到问题的正确方向。此外,如果您使用-Wall进行编译,则会收到有关第一个不返回任何内容的函数的警告。