2013-05-14 50 views
3

我是一個獨立寄宿學校的老師,我正試圖用C++編寫一個程序,它會隨機地讓學生坐在我們餐廳的桌子旁,讓他們坐在不同的學生和不同的工作人員旁邊周。理想情況下,在特定時期內,他們不會坐在同一張桌子上,並且儘可能與同一批人同坐。我用Python創建了這個程序,它工作得很好(很好,很好)。出於各種原因,我試圖將其轉移到C++(我根本不知道),所以我可以將它交給登機人員。從文本文件中讀取學生和工作人員(以及表格容量)。我創建了兩個自定義類,一個用於學生,另一個用於表格,用於處理數據。下面是這兩個類的頭文件:C++類的問題

Table.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周。我有一個整數矢量,它應該存儲學生隨着時間的推移而放置的表號。在調試時,我注意到那些表號不會被存儲在該向量中,它總是空的。我的問題是我無法弄清楚爲什麼會發生這種情況。是因爲我通過引用傳遞向量?它是否與指針有關,即使我沒有明確聲明指針?

任何建議,非常感謝,我可以粘貼其餘的代碼,如果有必要。

布賴恩

+7

聖牆文字,你的問題是什麼? – wich 2013-05-14 14:24:26

+1

什麼代碼調用seatRecursive? addStudentToTable裏面有什麼? – Sergi0 2013-05-14 14:27:28

+0

@wich,他想知道爲什麼學生的「表歷史」沒有被存儲。他的調試表明他的矢量「矢量 tablesSatAt」沒有被更新。 – 2013-05-14 14:29:48

回答

1

我看到StudentTable類的兩個拷貝構造函數(和賦值構造函數)忘記複製載體包含的STL(vector<Student> seatingvector<int> tablesSatAt)自定義類。既然你重載了這些構造函數,你應該通過vector拷貝構造函數來拷貝它們,因爲它沒有被隱式地完成。

如果不復制它們,每當一個StudentTable圍繞一個向量移動(或分配給一個臨時的)時,內部向量就會被新的對象拋棄。

正如在這種情況下無用評論所指出的那樣,你不需要聲明它們,因爲rule of three不適用:你不需要析構函數,所以你可能不需要這兩個拷貝構造函數。

注意:您在註釋中稱爲複製構造函數的是複製指派構造函數。前一個是真正的拷貝構造函數。

+6

或者根本不寫複製構造函數。編譯器生成的將會很好。 – Useless 2013-05-14 14:36:52

+0

奇怪的是,IIRC,直到我寫這兩個構造函數,代碼甚至不會編譯。當然,這可能完全是我做事的方式。我將嘗試刪除複製構造函數和複製STL向量的兩個建議。謝謝。 – user2378099 2013-05-14 15:29:43

+0

@Useless:關於複製構造函數是正確的,當我評論這些函數時,程序仍編譯正確。 – user2378099 2013-05-14 17:25:33

6

爲什麼讓它很難?

只需將所有學生放在一個矢量中,然後使用STL random_shuffle算法,最後將所得到的學生矢量線性地放在所有可用的表格中。

你甚至都不需要學生或表真的

+0

我仍然需要一種方式來跟蹤學生坐在哪裏,以便他們不重複表格。另外,由於每個表的可用座位數量不同,我需要一種方式來跟蹤該表以及分配給特定表的工作人員。 – user2378099 2013-05-14 16:59:47