3

我是一所独立寄宿学校的老师,我正在尝试用 C++ 编写一个程序,该程序将随机安排学生坐在我们食堂的桌子上,以便他们每周与不同的学生和不同的工作人员坐在一起。理想情况下,在给定的时间内,他们不会两次坐在同一张桌子上,并且尽可能多地与不同的学生坐在一起。我在 Python 中创建了这个程序,它运行良好(嗯,非常好)。出于各种原因,我正试图将其移植到 C++(我对此一无所知),以便将其交给寄宿人员。学生和教职员工(以及表格容量)都是从文本文件中读取的。我创建了两个自定义类,一个用于学生,一个用于表格,用于处理数据。这是两个类头文件:

表.h

#pragma once
#include <iostream>
#include "Student.h"
#include <vector>

using namespace std;

class Table
{
    // Private class variables
    string staff;
    int numSeats;
    vector<Student> seating;
public:
    Table(); // Default constructor
    Table(string s, int n);
    Table(const Table& that) : staff(that.staff), numSeats(that.numSeats)
    {
    }
    // Copy Constructor
    Table& operator=(const Table& that)
    {
        staff = that.staff;
        numSeats = that.numSeats;
        return *this;
    }
    int getNumSeats();
    string getStaffName();
    void addStudent(Student student);
    void removeStudent(Student student);
    void clearStudents();
    vector<Student> getTableSeating();
    int getRemainingSeats();
    ~Table(void);
};

这是学生类文件:

#pragma once
#include <iostream>
#include <vector>

using namespace std;

class Student
{
    string name;
    string country;
    vector<int> tablesSatAt;
public:
    Student(string n, string c);
    Student();
    Student(const Student& that) : name(that.name), country(that.country)
    {
    }
    Student& operator=(const Student& that)
    {
        name = that.name;
        country = that.country;
        return *this;
    }
    string getName();
    string getCountry();
    void addTable(int tableNumber);
    void removeTable(int tableNumber);
    bool satAtTable(int tableNumber);
    friend bool operator==(Student s1, Student s2);
    friend bool operator!=(Student s1, Student s2);
    ~Student(void);
};

bool operator==(Student s1, Student s2);
bool operator!=(Student s1, Student s2);

这是执行繁重工作的递归函数:

bool seatRecursive(vector<Student> &tempStudents, vector<Table> &tempTables)
{
    if (tempStudents.size() == 0) return true; //base case

    Student nextStudent = randomSelect(tempStudents);
    for (vector<int>::size_type i=0; i<tempTables.size(); i++)
    {
        if (tempTables[i].getRemainingSeats() > 0 && !nextStudent.satAtTable(i))
        {
            addStudentToTable(nextStudent, tempTables, i);
            if (seatRecursive(tempStudents, tempTables)) return true;
            else 
            {
                removeStudentFromTable(nextStudent, tempTables, i);
                tempStudents.push_back(nextStudent);
            }
        }
    }
    return false;
}

这大部分都有效。当我运行该程序时,我得到一个包含 10 周座位的文本文件,但所有的桌子座位都是一样的。即,如果我是一名特定的工作人员,那么我的餐桌上都会有相同的孩子整整 10 周。我有一个整数向量,它应该存储学生随着时间的推移而坐的表格编号。调试时,我注意到这些表号没有存储在该向量中,它始终为空。我的问题是我无法弄清楚为什么会这样。是因为我通过引用传递向量吗?即使我没有明确声明指针,它是否与指针有关?

非常感谢任何建议,如有必要,我可以粘贴其余代码。

布赖恩

4

2 回答 2

6

为什么要让它变得困难?

只需将所有学生放入一个向量中,然后使用 STL random_shuffle 算法,最后将结果向量线性放入所有可用表中。

你甚至不需要为学生或桌子定制课程

于 2013-05-14T14:29:21.067 回答
1

我看到StudentTable类的复制构造函数(和赋值构造函数)都忘记了复制包含的 STL 向量 (vector<Student> seatingvector<int> tablesSatAt)。由于您重载了这些构造函数,因此您应该通过vector复制构造函数复制它们,因为它不是隐式完成的。

在不复制它们的情况下,每次 aStudent或 aTable在向量周围移动(或分配给临时)时,内部向量都会被丢弃以用于新对象。

正如Useless在这种情况下的评论所指出的那样,您不需要声明它们,因为三规则不适用:您不需要析构函数,因此您可能不需要两个复制构造函数。

注意:您在评论中称为复制构造函数的是复制赋值构造函数。前一个是真正的复制构造函数。

于 2013-05-14T14:33:45.657 回答