似乎无法找到无限循环的理由

时间:2011-03-18 03:24:31

标签: c++ sorting loops infinite-loop

我正在编写一个程序,帮助整理4年制大学的课程。由于某种原因,我陷入了while循环。

/*
some info:
"course" is a class i created
   some of the member function are:
      bool fall()           // does the class run in the fall?
      bool spring()         // does the class run in the spring?
      string name()         // name of this course
      ...                   // plenty of irrelevant stuff


"classes" is a vector of courses
"vector <vector <course> > out" has n (generally 8) elements

"vector <string> taken" records the names of the courses that have been taken

bool prereq_taken(course C, vector <string> & taken) checks if all the 
prerequisites of the course are taken

even semesters are fall and odd are spring

*/


int x = 0, semester = 0;
while ((classes.size() > 0)){
    x %= classes.size();

if (prereq_taken(classes[x], taken)){                                            // checks if all of the prerequisites in the course have already been taken

    // my test condition
    //if ((semester % 2 == 0) && classes[x].fall() && (!classes[x].spring())){

    // Ben's condtion
    if ((semester & 1)? classes[x].spring(): classes[x].fall()){

    // my retardedly long all-in-one condition
    /*if (
        (((!(semester % 2)) && classes[x].fall() && (!classes[x].spring()))    // if fall and is only fall class or
        || ((semester % 2) && (!classes[x].fall()) && classes[x].spring())     // if spring and is only spring class
        || (classes[x].fall() && classes[x].spring())                          // if any semester class

        )                                                                      // and there is class space and enough credit space
        && (((out[semester].size() + 1) < classes_per_semester) && ((credits[semester] + classes[x].credits()) < credits_per_semester))) {
    */
        taken.push_back(classes[x].name());                                      // put class name into vector of takens
        out[semester].push_back(classes[x]);                                     // put class into final output
        classes.erase(classes.begin() + x);                                      // remove from class list
    }
    else
        x++;

 }
    else
        x++;                                                                         // else go to next class

    if ((out[semester].size() + 1) > classes_per_semester)
        semester++;
}

我正在尝试浏览所有数据(并循环播放),直到所有课程都已正确放置

出于某种原因,当我在if语句中添加星星时,循环会一直持续。但是,没有它和else的东西(但内部的东西仍在代码中),代码将完成。为什么?是c ++布尔数学有点不同于python(对这段代码很重要)?

如果我以任何方式模糊,请告诉我要澄清什么

3 个答案:

答案 0 :(得分:2)

您认为这是做什么的?

if ((x == classes.size()))
    x %= classes.size();

作业与:

相同
   x = x % classes.size();

但你刚发现x == classes.size()所以

   x = classes.size() % classes.size();

对于任何NN%N为零,这意味着

if ((x == classes.size()))
    x = 0;

这就是你想要的吗?


有问题的if只能处理仅在秋季提供的课程。也许你想要:

if ((semester & 1)? classes[x].spring(): classes[x].fall()) { ... }

也许这会起作用?

int x = 0, semester = 0, scheduled = 0;
vector<string> completed;
while ((classes.size() > 0)) {
    if (classes.size() == x) {
        x = 0;
        cout << "Checked all classes and scheduled " << scheduled << endl;
        if (0 == scheduled) {
            ++semester;
            completed = taken;
        }
        scheduled = 0;
    }

    if (prereq_taken(classes[x], completed)) {
        if ((semester & 1)? classes[x].spring(): classes[x].fall()) {
            if (credits[semester] + classes[x].credits() <= credits_per_semester) {
                taken.push_back(classes[x].name());
                out[semester].push_back(classes[x]);
                credits[semester] += classes[x].credits();
                cout << classes[x].name() << " will be taken in semester " << semester << " for " << classes[x].credits() << " credits" << endl;
                classes.erase(classes.begin() + x);
                scheduled++;
            }
            else {
               cout << classes[x].name() << " can't be taken in semester " << semester << " : overload on credits" << endl;
               x++;
            }
        }
        else {
            cout << classes[x].name() << " can't be taken in semester " << semester << " : not offered" << endl;
            x++;
        }    
     }
     else {
        cout << classes[x].name() << " can't be taken in semester " << semester << " : not offered" << endl;
        x++;                                                                         // 
     }

     if (out[semester].size() >= classes_per_semester || credits[semester] >= credits_per_semester) {
        cout << "Full load reached for semester " << semester << endl;
        semester++;
        completed = taken;
     }
}

答案 1 :(得分:2)

我认为问题是你永远无法满足所有课程的要求。已加星标的代码

if ((semester % 2 == 0) && classes[x].fall() && (!classes[x].spring())){

只允许你参加秋季课程。如果必修课程仅在春季开课,则由于缺少要求,您的代码将尝试分配无法添加新课程的课程。

现在,我们假设你修复if并允许完成课程要求。您仍然依赖于正确的数据(即没有循环过程依赖性)。我建议您阅读topological sorting,以防您不熟悉它。处理无限循环可能性的一种简单(尽管效率低)的方法是使用观察结果,在整个课程列表的每一步中,应该至少从列表中删除一个课程。所以你可以这样写:

int x = 0, semester = 0, prev_size = classes.size();
while ((classes.size() > 0)){
    if (x == classes.size()){
        x = 0;
        if( classes.size() == prev_size ) { // no courses removed in the last cycle
            // signal error
            break;
        }
        else
            prev_size = classes.size();
    }
    ...
}

答案 2 :(得分:1)

&本身就是一个按位而且。你想要一个&&。可能永远不会达到if语句中的那个部分,因此大小不会改变。