I'm attempting to print out the 640 paths in this subway system. I know there are 640 paths, as I already did this program with an adjacency matrix. Now I need to do it with classes. The first station begins at 'a', and the path ends at station 'l'. I am having trouble implementing the recursive function, SearchRoute, as I need to print the path, flag the path, and then unflag the path again to allow for backtracking. Currently I can only print the track that is 'a' to 'b', so something is severely wrong with my recursive function. Any advice would be appreciated
header
//Function Declarations
#include <iostream>
#include <string>
using namespace std;
#ifndef SUBWAY_H
#define SUBWAY_H
class Track
{
public:
//Default Constructor
Track();
//Overload Constructor
Track(char, char);
//Destructor
~Track();
//Member variables
char node_1;
char node_2;
bool visited;
};
class Station
{
public:
//Default Constructor
Station();
//Destructor
~Station();
//Overload Constructor
Station(char, int, int);
//Member variables
char station_name;
int track_starting_ID;
int track_size;
};
class SubwaySystem
{
public:
//Default Constructor
SubwaySystem();
//Destructor
~SubwaySystem();
//Recursive function
void SearchRoute(int);
//Other member functions
friend ostream& operator<<(ostream& os, const Track& my_track);
friend ostream& operator<<(ostream& os, const Station& my_station);
//Member variables
Track my_track[34];
Station my_station[12];
int count_routes;
int Current_Station_ID;
//String to save found route
};
#endif
cpp
//Function Definitions
#include <iostream>
#include <string>
#include "subway.h"
using namespace std;
Track::Track()
{
visited = 0;
}
Track::~Track(){
}
Track::Track(char pass_track1, char pass_track2)
{
node_1 = pass_track1;
node_2 = pass_track2;
}
Station::Station(){
}
Station::~Station(){
}
Station::Station(char pass_station_name, int pass_start, int pass_size){
station_name = pass_station_name;
track_starting_ID = pass_start;
track_size = pass_size;
}
SubwaySystem::SubwaySystem()
{
//Initialize tracks
//node_1, node_2
my_track[0] = Track('a', 'b');
my_track[1] = Track('b', 'a');
my_track[2] = Track('b', 'c');
my_track[3] = Track('b', 'd');
my_track[4] = Track('b', 'e');
my_track[5] = Track('b', 'f');
my_track[6] = Track('c', 'b');
my_track[7] = Track('c', 'e');
my_track[8] = Track('d', 'b');
my_track[9] = Track('d', 'e');
my_track[10] = Track('e', 'b');
my_track[11] = Track('e', 'c');
my_track[12] = Track('e', 'd');
my_track[13] = Track('e', 'g');
my_track[14] = Track('e', 'h');
my_track[15] = Track('f', 'b');
my_track[16] = Track('f', 'h');
my_track[17] = Track('g', 'e');
my_track[18] = Track('g', 'k');
my_track[19] = Track('h', 'e');
my_track[20] = Track('h', 'f');
my_track[21] = Track('h', 'i');
my_track[22] = Track('h', 'j');
my_track[23] = Track('h', 'k');
my_track[24] = Track('i', 'h');
my_track[25] = Track('i', 'k');
my_track[26] = Track('j', 'h');
my_track[27] = Track('j', 'k');
my_track[28] = Track('k', 'g');
my_track[29] = Track('k', 'h');
my_track[30] = Track('k', 'i');
my_track[31] = Track('k', 'j');
my_track[32] = Track('k', 'l');
my_track[33] = Track('l', 'k');
//Initialize stations
//station_name, track_starting_ID, track_size
my_station[0] = Station ('a', 0, 1);
my_station[1] = Station ('b', 1, 5);
my_station[2] = Station ('c', 6, 2);
my_station[3] = Station ('d', 8, 2);
my_station[4] = Station ('e', 10, 5);
my_station[5] = Station ('f', 15, 2);
my_station[6] = Station ('g', 17, 2);
my_station[7] = Station ('h', 19, 5);
my_station[8] = Station ('i', 24, 2);
my_station[9] = Station ('j', 26, 2);
my_station[10] = Station ('k', 28, 5);
my_station[11] = Station ('l', 33, 1);
//Initiaize other members
count_routes = 0;
Current_Station_ID = 0;
}
SubwaySystem::~SubwaySystem()
{
}
ostream& operator<<(ostream& os, const Track& my_track)
{
os << my_track.node_1 << '.' << my_track.node_2;
return os;
}
ostream& operator<<(ostream& os, const Station& my_station)
{
os << my_station.station_name << '.' << my_station.track_starting_ID << '.' << my_station.track_size;
return os;
}
void SubwaySystem::SearchRoute(int Current_Station_ID)
{
while (Current_Station_ID < 33)
{
if (Current_Station_ID == 0) //Find a successful route to Station L
{
count_routes++; //Add 1 into the variable “count_routes”
cout << count_routes << " " << my_track[Current_Station_ID] << endl; //Print out this route
return;
}
else //Get into recursive Function Body
{
for (int i = my_station[Current_Station_ID].track_starting_ID; i < my_station[Current_Station_ID].track_starting_ID + my_station[Current_Station_ID].track_size; i++)
{
if (my_track[Current_Station_ID].visited == 0) //if this track is not visited before
{
my_track[Current_Station_ID].visited = 1; //mark this track as visited
my_track[Current_Station_ID].node_2 = 1; //mark its corresponding track as visited
cout << my_track[Current_Station_ID] << endl; //save this track
SearchRoute(Current_Station_ID + 1); //Recursive
i--; //Backtrack this track
my_track[Current_Station_ID].visited = 0;//mark this track as unvisited
my_track[Current_Station_ID].node_2 = 0;//mark its corresponding track as unvisited
}
}
}
}
}
main
#include <iostream>
#include <string>
#include "subway.h"
using namespace std;
int main(int argc, char **argv)
{
SubwaySystem Test;
Test.SearchRoute(0);
}
Why is there a return statement in
if (Current_Station_ID == 0) //Find a successful route to Station L
{
count_routes++; //Add 1 into the variable “count_routes”
cout << count_routes << " " << my_track[Current_Station_ID] << endl; //Print out this route
return;
}
(Probably worthy of only a comment, but I hate pasting code in comments)
As far I can see you have not initialized all members in the constructor. At least in the Track. The right ctor looks like:
Track::Track(char pass_track1, char pass_track2)
{
node_1 = pass_track1;
node_2 = pass_track2;
visited = false; // this was missing
}
In C++ you have to initialize all members in all constructors. Otherwise the values has the values which was before in the memory. The chance that there is a 0 in the visited member is 1:2^32 => near to zero.
Hi @ace : much as Frank suggested you need to initialise all variables. However I would also include a default constructor which makes single piece tracks and utilises the overloaded constructor:
Track::Track() { Track("~","~"); }
Track::Track(char pass_track1, char pass_track2)
{
node_1 = pass_track1;
node_2 = pass_track2;
visited = false;
}
This means the base constructor will always make a single piece track from "~" to "~" (can be any character) I would also use a character for the base constructor which you will not use in real use, that way you can track and trace problems in the future and it becomes evident when the default constructor is being utilised at a glance, simply because it contains said character of your choice.
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.