Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm attempting to implement a limit order book in C++ (a very simple one) by having a std::map where the keys are price points and the values are PricePoint objects.
The Book class has two of these, bid and ask to store the buys and sells (respectively).
#include <iostream>
#include <map>
#include <list>
using namespace std;
#define MAX_NUM_ORDERS 512
class Order
{
public:
unsigned int id;
unsigned int price;
unsigned int volume;
bool side;
time_t added;
time_t executed;
time_t cancelled;
Order *next;
Order *prev;
Order(unsigned int price, unsigned int volume, bool side)
{
this->id = 0;
this->price = price;
this->volume = volume;
this->side = side;
this->added = 0;
this->executed = 0;
this->cancelled = 0;
this->next = 0;
this->prev = 0;
}
};
class PricePoint
{
public:
Order *head;
Order *tail;
PricePoint(void)
{
this->head = 0;
this->tail = 0;
}
void insertAfter(Order *node, Order new_node)
{
new_node.next = node->next;
if(node->next == 0)
{
this->tail = &new_node;
}
else
{
node->next->prev = &new_node;
}
node->next = &new_node;
}
void insertHead(Order new_node)
{
if(this->head == 0)
{
this->head = &new_node;
this->tail = &new_node;
new_node.prev = 0;
new_node.next = 0;
}
else
{
insertAfter(this->tail, new_node);
}
}
void insertTail(Order new_node)
{
if (this->tail == 0)
{
insertHead(new_node);
}
else
{
insertAfter(this->tail, new_node);
}
}
unsigned int count(void)
{
unsigned int i;
Order node(0, 0, false);
while(node.next == 0)
{
for(i=0;i<=MAX_NUM_ORDERS;i++)
{
// lol
}
}
return i;
}
bool empty(void)
{
if(this->head == 0)
{
return true;
}
else
{
return false;
}
}
void print(void)
{
if(this->empty() == true)
{
cout<<"[None]"<<endl;
return;
}
else
{
if(this->head != 0)
{
unsigned int i;
Order *node = this->head; // start at the head
cout<<"id, volume, added"<<endl; // labels
while(node->next != 0) // while we're not at the end
{
cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
node = node->next;
}
}
else // try and catch it again i guess?
{
cout<<"[None]"<<endl;
return;
}
}
}
};
class Book
{
public:
map<int, PricePoint> bid; // buy-side
map<int, PricePoint> ask; // sell-side
int add(Order order)
{
order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers
if(order.side == false) // buy order
{
if(this->bid.count(order.price) == 0) // if the price point isn't already there
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
else
{
this->bid[order.price].insertTail(order); // insert at tail of the doubly linked list
}
}
else if(order.side == true) // sell order
{
if(this->bid.count(order.price) == 0)
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
{
this->ask[order.price].insertTail(order); // insert at the tail of the doubly linked list
}
}
return order.id; // the order's id
}
int cancel(unsigned int id)
{
}
void print(void)
{
unsigned int i = 0;
cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
cout<<this->bid.size()<<endl;
for(i=0;i<this->bid.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->bid[i].print();
}
i = 0;
cout<<endl;
cout<<"-------------------------------------ASKS--------------------------------------"<<endl;
for(i=0;i<this->ask.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->ask[i].print();
}
cout<<endl;
}
};
int main(void)
{
unsigned int i;
Book orderbook; // our limit order book
// some orders
Order a(4, 33, false);
Order b(4, 12, true);
Order c(5, 33, true);
//add them
orderbook.add(a);
orderbook.add(b);
orderbook.add(c);
cout<<"Order book is as follows:"<<endl;
orderbook.print();
system("pause");
return 0;
}
I want to print the order book, but when I attempt to traverse the list I am met with unhandled exceptions, like so:
Unhandled exception at 0x00a418aa in orderbook.exe: 0xC0000005: Access violation reading location 0x00000039.
In the debugger, I'm seeing that the next pointer is eventually becoming junk, indicative I've failed to initialise correctly, yes?
Also, the program outputs junk data (also indicative of uninitialised pointers) before excepting.
Any help is much appreciated, thanking you very much.
These:
void insertAfter(Order *node, Order new_node)
void insertHead(Order new_node)
void insertTail(Order new_node)
insert a pointer to a local variable. They have to take a pointer:
void insertAfter(Order *node, Order* new_node)
void insertHead(Order* new_node)
void insertTail(Order* new_node)
try this (and correct it, i guess):
#include <iostream>
#include <map>
#include <list>
using namespace std;
#define MAX_NUM_ORDERS 512
class Order
{
public:
unsigned int id;
unsigned int price;
unsigned int volume;
bool side;
time_t added;
time_t executed;
time_t cancelled;
Order *next;
Order *prev;
Order(unsigned int price, unsigned int volume, bool side)
{
this->id = 0;
this->price = price;
this->volume = volume;
this->side = side;
this->added = 0;
this->executed = 0;
this->cancelled = 0;
this->next = 0;
this->prev = 0;
}
};
class PricePoint
{
public:
Order *head;
Order *tail;
PricePoint(void)
{
this->head = 0;
this->tail = 0;
}
void insertAfter(Order *node, Order* new_node)
{
new_node->next = node->next;
if(node->next == 0)
{
this->tail = new_node;
}
else
{
node->next->prev = new_node;
}
node->next = new_node;
}
void insertHead(Order* new_node)
{
if(this->head == 0)
{
this->head = new_node;
this->tail = new_node;
new_node->prev = 0;
new_node->next = 0;
}
else
{
insertAfter(this->tail, new_node);
}
}
void insertTail(Order* new_node)
{
if (this->tail == 0)
{
insertHead(new_node);
}
else
{
insertAfter(this->tail, new_node);
}
}
unsigned int count(void)
{
unsigned int i;
Order node(0, 0, false);
while(node.next == 0)
{
for(i=0;i<=MAX_NUM_ORDERS;i++)
{
// lol
}
}
return i;
}
bool empty(void)
{
if(this->head == 0)
{
return true;
}
else
{
return false;
}
}
void print(void)
{
if(this->empty() == true)
{
cout<<"[None]"<<endl;
return;
}
else
{
if(this->head != 0)
{
unsigned int i;
Order *node = this->head; // start at the head
cout<<"id, volume, added"<<endl; // labels
while(node->next != 0) // while we're not at the end
{
cout<<node->id<<", "<<node->volume<<", "<<node->added<<endl;
node = node->next;
}
}
else // try and catch it again i guess?
{
cout<<"[None]"<<endl;
return;
}
}
}
};
class Book
{
public:
map<int, PricePoint> bid; // buy-side
map<int, PricePoint> ask; // sell-side
int add(Order order)
{
order.id = this->bid.size() + this->ask.size() + 1; // this way, buy-side and sell-side orders have unique identifiers
if(order.side == false) // buy order
{
if(this->bid.count(order.price) == 0) // if the price point isn't already there
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
bid.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
else
{
this->bid[order.price].insertTail(&order); // insert at tail of the doubly linked list
}
}
else if(order.side == true) // sell order
{
if(this->bid.count(order.price) == 0)
{
PricePoint pp;
pair<int, PricePoint> new_pp(order.price, pp);
ask.insert(new_pp); // add the price point (i.e. add an entry to the map)
}
{
this->ask[order.price].insertTail(&order); // insert at the tail of the doubly linked list
}
}
return order.id; // the order's id
}
int cancel(unsigned int id)
{
}
void print(void)
{
unsigned int i = 0;
cout<<"-------------------------------------BIDS--------------------------------------"<<endl;
cout<<this->bid.size()<<endl;
for(i=0;i<this->bid.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->bid[i].print();
}
i = 0;
cout<<endl;
cout<<"-------------------------------------ASKS--------------------------------------"<< ask.size() <<endl;
for(i=0;i<this->ask.size();i++)
{
cout<<"Orders for $"<<i<<":"<<endl;
this->ask[i].print();
}
cout<<endl;
}
};
int main(void)
{
unsigned int i;
Book orderbook; // our limit order book
// some orders
Order a(4, 33, false);
Order b(4, 12, true);
Order c(5, 33, true);
//add them
orderbook.add(a);
orderbook.add(b);
orderbook.add(c);
cout<<"Order book is as follows:"<<endl;
orderbook.print();
// system("pause");
return 0;
}
Related
I'm challenging myself to create my own custom integer array by making a class and structure with some functions. When I run the program I don't get an error, but the data of the index isn't being set, and I don't understand why.
Array class file
#include "IntArray.hpp"
using namespace std;
struct IntArrayIndex {
public:
IntArrayIndex* next = NULL;
int data;
IntArrayIndex(int Data) {
this->data = Data;
}
IntArrayIndex() {
this->data = 0;
}
};
class IntArray {
public:
IntArrayIndex head = *(new IntArrayIndex());
int length;
IntArray() {
this->length = 1;
this->head = *(new IntArrayIndex());
}
int getIndex(int index) {
if (index >= length) {
throw invalid_argument("Index out of range. Returned -1");
}
IntArrayIndex current = head;
if (index > 0) {
current = *current.next;
getIndex(--index);
}
return current.data;
}
void setIndex(int index, int data) {
IntArrayIndex current = head;
if (index > 0) {
if (current.next == NULL) {
current.next = new IntArrayIndex();
length++;
}
current = *current.next;
setIndex(--index, data);
}
current.data = data;
}
};
Main file
#include <iostream>
#include "IntArray.cpp"
int main(int argc, const char * argv[]) {
IntArray* l = new IntArray();
l->setIndex(0, 1);
std::cout << l->getIndex(0);
}
OUTPUT:
0
Program ended with exit code: 0
Changing the pointers in setIndex ended up fixing the problem:
void setIndex(int index, int data) {
IntArrayIndex* current = &head;
if (index > 0) {
if (current->next == NULL) {
current->next = new IntArrayIndex();
length++;
}
current = current->next;
setIndex(--index, data);
}
current->data = data;
}
When I study the DataStructrue in my school, I implemented the Queue.
School's DataStructure class process is below.
student implemnted the DS
student submit in Domjudge
Domjudge score the code based by test cases.
My freind implemented the Queue like below.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
int data;
Node* next;
Node() {}
Node(int e) {
this->data = e;
this->next = NULL;
}
~Node(){}
};
class SLinkedList {
public:
Node* head;
Node* tail;
SLinkedList() {
head = NULL;
tail = NULL;
}
void addFront(int X) {
Node* v = new Node(X); // new Node
if (head == NULL) {
// list is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int removeFront() {
if (head == NULL) {
return -1;
}else{
Node* tmp = head;
int result = head->data;
head = head->next;
delete tmp;
return result;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
void addBack(int X) {
Node* v = new Node(X);
if (head == NULL) {
head = tail = v;
}else {
tail->next = v;
tail = v;
}
}
~SLinkedList() {}
};
class LinkedQ {
public:
int n = 0;
int capacity;
Node* f;
Node* r;
SLinkedList Q;
LinkedQ(int size) {
capacity = size;
f = NULL;
r = NULL;
}
bool isEmpty() {
return n == 0;
}
int size() {
return n;
}
int front() {
return Q.front();
}
int rear() {
return Q.rear();
}
void enqueue(int data) {
if (n == capacity) {
cout << "Full\n";
}else {
Q.addBack(data);
n++;
}
}
};
int main() {
int s, n;
string cmd;
cin >> s >> n;
listQueue q(s);
for (int i = 0; i < n; i++) {
cin >> cmd;
if (cmd == "enqueue") {
int x;
cin >> x;
q.enqueue(x);
}else if (cmd == "size") {
cout << q.size() << "\n";
}else if (cmd == "isEmpty") {
cout << q.isEmpty() << "\n";
}else if (cmd == "front") {
q.front();
}else if (cmd == "rear") {
q.rear();
}
}
}
And I implmented like this (Node class and main are same, So I pass the code)
#include <iostream>
#include <string>
using namespace std;
class Node{...};
class listQueue {
public:
Node* head;
Node* tail;
int capacity;
int n = 0;
listQueue() {
head = NULL;
tail = NULL;
}
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) {
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
int front() {
if (head == NULL) {
return -1;
}else {
return head->data;
}
}
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
int empty() {
if (head == NULL) {
return 1;
}else {
return 0;
}
}
~listQueue() {}
};
test cases are just enqueue
but my friend is correct, and my code has occured memory over error.
So I check the usage of memory in Domjudge, My friend code and My code has very big gap in memory usage.
Why these two codes have memory usage gap big?
P.S I can't speak English well. If there is something you don't understand, please tell me.
First, rear is incorrect. It checks head and return tail. It happens to correct when you first set head=tail=v but it might get wrong later.
int rear() {
if (head == NULL) {
return -1;
}else {
return tail->data;
}
}
Check the if statement below:
v is leaked if queue is full in enqueue in your implementation.
Don't use NULL in C++. You may refer to NULL vs nullptr (Why was it replaced?).
void enqueue(int X) {
Node* v = new Node(X); // new Node
if (n==capacity) { // You're leaking v;
cout << "Full\n";
return;
}
if (head == NULL) {
// Queue is empty
head = tail = v;
}else {
v->next = head;
head = v;
}
}
I've been having some trouble getting my program to insert given names along with their weights in a linked list which has a respective link for names and weights, which are both to be sorted in ascending / alphabetical order. The weight links work fine but I can't seem to identify what I'm getting wrong in my name linker. Any help would be greatly appreciated. The problem most likely lies in the insertName() private function.
#include <iostream>
#include <string>
using namespace std;
class DoublyLinkedList
{
public:
void insert(string name, double weight);
void printNameAsc();
void printWeightAsc();
private:
struct Node
{
string name;
double weight;
Node* nextName;
Node* nextWeight;
};
Node* nameHead = NULL;
Node* weightHead = NULL;
Node* newP = NULL;
void insertName();
void insertWeight();
};
void DoublyLinkedList::insert(string name, double weight)
{
// variable declaration
newP = new Node;
newP->name = name;
newP->weight = weight;
newP->nextName = NULL;
newP->nextWeight = NULL;
// empty first element check
if (nameHead == NULL && weightHead == NULL)
{
nameHead = newP;
weightHead = newP;
return;
}
// name and weight insertion
insertName();
insertWeight();
return;
}
void DoublyLinkedList::insertName()
{
Node* activeP = nameHead;
Node* prevP = NULL;
// traversing through name links
while (true)
{
if (activeP == NULL)
{
break;
}
if ((activeP->name).compare(newP->name))
{
break;
}
prevP = activeP;
activeP = activeP->nextName;
}
//insertion
newP->nextName = activeP;
if (activeP == nameHead)
{
nameHead = newP;
}
else
{
prevP->nextName = newP;
}
return;
}
void DoublyLinkedList::insertWeight()
{
Node* activeP = weightHead;
Node* prevP = NULL;
// traversing through weight links
while (true)
{
if (activeP == NULL)
{
break;
}
if (newP->weight < activeP->weight)
{
break;
}
prevP = activeP;
activeP = activeP->nextWeight;
}
//insertion
newP->nextWeight = activeP;
if (activeP == weightHead)
{
weightHead = newP;
}
else
{
prevP->nextWeight = newP;
}
return;
}
void DoublyLinkedList::printNameAsc()
{
Node* activeP = nameHead;
while (activeP != NULL)
{
cout << activeP->name << " " << activeP->weight << endl;
activeP = activeP->nextName;
}
return;
}
void DoublyLinkedList::printWeightAsc()
{
Node* activeP = weightHead;
while (activeP != NULL)
{
cout << activeP->name << " " << activeP->weight << endl;
activeP = activeP->nextWeight;
}
return;
}
int main()
{
DoublyLinkedList nameList;
nameList.insert("Michael", 275);
nameList.insert("Tom", 150);
nameList.insert("Abe", 200);
nameList.printNameAsc();
system("pause");
nameList.printWeightAsc();
system("pause");
return 0;
}
Pretty sure your problem is here:
if ((activeP->name).compare(newP->name) > 0)
{
break;
}
Looks like you're finding the insertion point with activeP. When activeP->name > newP->name, you want to stop searching.
if ((activeP->name).compare(newP->name))
Is invalid, this will evaluate true if activeP < newP (compare statement is -1) or activeP > newP (compare statement is 1), effectively only skipping people with the same names.
Remember, carried over from C, truth is defined as not falseness, which is defined as (!0)
Also, why not just pass a reference of newP to insertName() and insertWeight()? It's good practice to not leave (possibly dangling) pointers stored as member variables.
I tried to implement BFS for graphs using link list but i have some issues with it, using a queue it only displays the nodes of that origin and not after it. The answer should be 2031 but i only get 203.
The code is below:
#include <iostream>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <queue>
using namespace std;
class linkListNode
{
public:
linkListNode *next;
int destination;
bool visited;
linkListNode()
{
next = NULL;
destination =0;
visited=false;
}
};
class linkList
{
public:
linkListNode *head;
linkList()
{
head = NULL;
}
// append type insert
void insert(int value)
{
linkListNode *temp2 = new linkListNode;
temp2->destination = value;
temp2->next = NULL;
linkListNode *nodePtr = new linkListNode;
if (head == NULL)
{
head = temp2;
temp2->next = NULL;
}
else
{
nodePtr = head;
while (nodePtr->next)
{
nodePtr = nodePtr->next;
}
nodePtr->next = temp2;
}
}
void display()
{
linkListNode *temp = new linkListNode;
temp = head;
while (temp)
{
cout << temp->destination << " --> ";
temp = temp->next;
}
cout << endl;
}
int size()
{
linkListNode *temp = head;
int sizer = 0;
while (temp)
{
sizer++;
temp = temp->next;
}
return sizer;
}
};
class edge
{
public:
int origin;
linkList final;
bool visited;
edge()
{
//origin = NULL;
//cost=0;
visited=false;
}
};
class graph
{
private:
vector <edge> vectorOfEdges;
int vertices;
public:
graph(int v)
{
vertices = v;
vectorOfEdges.clear();
}
void addRoute(int ori, int dest)
{
int counter = 0;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin== ori)
{
counter = 1; // means element was present in the list
e.final.insert(dest);
}
vectorOfEdges[i] = e;
}
if (counter == 0) // when counter is set to zero, this means that the element was not found in the vector and needs to be pushed
{
edge e;
e.origin = ori;
e.final.insert(dest);
vectorOfEdges.push_back(e);
}
}
void printGraph()
{
edge e;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
e = vectorOfEdges[i];
cout << e.origin << ":- ";
e.final.display();
cout << endl;
}
}
int sizeOfEdge(edge e)
{
int x = e.final.size() + 1;
return x;
}
int max(int one, int two)
{
if (one > two)
{
return one;
}
else
{
return two;
}
}
void BFS(int start)
{
edge e;
queue <int> q;
int save_index=0;
for (int i=0;i<vectorOfEdges.size();i++)
{
e=vectorOfEdges[i];
if (e.origin == start)
{
save_index=i;
q.push(e.origin);
e.visited=true;
break;
}
}
while (!q.empty())
{
int x=q.front();
cout << x << " " ;
q.pop();
linkListNode *l = e.final.head;
while (l)
{
if (l->visited == false)
{
q.push(l->destination);
l->visited=true;
l=l->next;
}
else
{
l=l->next;
}
}
}
}
};
int main()
{
graph g(4);
g.addRoute(0, 1);
g.addRoute(0, 2);
g.addRoute(1, 2);
g.addRoute(2, 0);
g.addRoute(2, 3);
// g.printGraph();
//cout << "Following is Breadth First Traversal (starting from vertex 2) \n";
g.BFS(1);
}
Your code is only running for the node that you have provided as the starting value for your BFS traversal.
void BFS(int start)
{
queue<int> q;
bool startFound = false;
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == start)
{
q.push(e.origin);
check.push_back(e.origin);
e.visited = true;
startFound = true;
break;
}
}
if (!startFound)
{
cout << "Start vertex not found in the graph" << endl;
return;
}
while (!q.empty())
{
int x = q.front();
cout << x << " ";
q.pop();
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == x)
{
linkListNode *l = e.final.head;
while (l != NULL)
{
bool found = false;
if (l->visited == false)
{
l->visited = true;
for (int i = 0; i < check.size(); i++)
{
if (check[i] == l->destination)
{
found = true;
break;
}
}
if (found == false)
{
check.push_back(l->destination);
q.push(l->destination);
}
}
l = l->next;
}
}
}
}
}
Instead, do this to run it for every node.
I have searched through the other questions and none of them seem to apply
exactly.
I am writing a program that finds a route through a maze,
the only real thing im having a problem with is this one compiler error.
It has to do with the one function I have the returns a Node ( struct).
Header file: (I cut the define stuff off)
#include <iostream>
#include <string>
using namespace std;
class Graph {
private:
struct Node {
int id; //int id
Node * north; //north path node
Node * south; //south path node
Node * east; //east path node
Node * west; //went path node
bool visited; // visited bool
};
//this struct holds the path that is found.
struct Elem {
int id; //The id of the node
string last; //the door that it passed through
Elem * back; //back one path
Elem * next; //forward one path
};
//This is a graph with a very smart struct
//This is the main node that makes up the graph.
Node * start;
Node ** initArr;
int arrLen;
Elem * head;
Elem * tail;
int path;
public:
Graph();
//Constructs empty graph
Graph(const Graph &v);
//copy constructor
~Graph();
//destructor
Graph & operator = (const Graph &v);
//assignment operator
void output(ostream & s) const;
//Prints the graph
void input(istream & s);
//input and creates the graph
Node * find(int id);
//finds the node in the graph
void makePath();
//makes a path through the maze
bool findPath(Node* cur, string room);
//worker function for recursion
void pathOut(ostream & s) const;
//Outputs the found path
void removeTail();
//Removes the last element
void addTail(Node* n, string door);
//Adds the element to the tail
//Mutators
void setId(Node* n ,int x);
void setVisited(Node* n, bool v);
//Elem Mutator
void seteId(Elem* e, int x);
//Elem Accessor
int geteId(Elem* e);
//Accessors
int getId(Node* n);
bool getVisited(Node* n);
};
And my actual code file.
#include <iostream>
#include "graph.h"
using namespace std;
//Constructs empty graph
Graph::Graph()
{
start = 0;
head = tail = 0;
path = 0;
}
//copy constructor
Graph::Graph(const Graph &v)
{
//not implemented
}
//destructor
Graph::~Graph()
{
for(int i = 0; i < arrLen + 1; i++)
{
delete initArr[i];
}
while(head != 0)
{
Elem* p = head;
head = head->next;
delete p;
}
delete[] initArr;
}
//assignment operator
Graph & Graph::operator = (const Graph &v)
{
//not implemented
}
//Prints the graph
void Graph::output(ostream & s) const
{
s<<"Node"<<'\t'<<"North"<<'\t'<<"East"<<'\t'<<"South"<<'\t'<<"West"<<'\n';
for(int i = 1; i < arrLen + 1; i++)
{
Node* temp = initArr[i];
s<<temp->id<<'\t';
if(temp->north != 0)
s<<temp->north->id<<'\t';
else
s<<"--"<<'\n';
if(temp->east != 0)
s<<temp->east->id<<'\t';
else
s<<"--"<<'\n';
if(temp->south != 0)
s<<temp->south->id<<'\t';
else
s<<"--"<<'\n';
if(temp->west != 0)
s<<temp->west->id<<'\t';
else
s<<"--"<<'\n';
s<<'\n';
}
}
//input and creates the graph
void Graph::input(istream & s)
{
int length = 0;
s>>length;
arrLen = length;
if(s)
{
//define array
initArr = new Node*[length + 1];
int temp = 0;
for(int i = 1; i < length + 1; i++)
{
//Create node
s>>temp;
Node* n = new Node;
n->id = temp;
n->visited = false;
//Add to array
initArr[i] = n;
}
//Make Exit Node
Node *x = new Node;
x->id = 0;
x->visited = false;
initArr[0] = x;
//Loop through all of the node input
int tn = 0;
for(int f = 0; f < length; f++)
{
//Set Pointers
s>>tn;
Node* curNode = find(tn);
int n = 0;
int e = 0;
int st = 0;
int w = 0;
s>>n>>e>>st>>w;
curNode->north = find( n );
curNode->east = find( e );
curNode->south = find( st );
curNode->west = find( w );
}
//set Entry point to graph
int last = 0;
s>>last;
start = find(last);
}
}
//finds the node in the array
Node* Graph::find(int id)
{
if( id == 0)
{
return initArr[0];
}
if(id == -1)
{
return 0;
}
else
{
for(int i = 1; i < arrLen + 1; i++)
{
if(initArr[i]->id == id)
{
return initArr[i];
}
}
cerr<<"NOT FOUND IN GRAPH";
return 0;
}
}
//makes a path through the maze
void Graph::makePath()
{
if(findPath(start->north, "north") == true)
{
path = 1;
return;
}
else if( findPath(start->east, "east") == true)
{
path = 1;
return;
}
else if( findPath(start->south, "south") == true)
{
path = 1;
return;
}
else if( findPath(start->west, "west") == true)
{
path = 1;
return;
}
return;
}
//finds a path to the outside
bool Graph::findPath(Node* cur, string room)
{
addTail(cur, room);
if(cur = initArr[0])
{
return true;
}
if(cur->north != 0 && cur->north->visited == false)
{
cur->visited = true;
findPath(cur->north, "north");
}
else if(cur->east != 0 && cur->east->visited == false)
{
cur->visited = true;
findPath(cur->north, "east");
}
else if(cur->south !=0 && cur->south->visited == false)
{
cur->visited = true;
findPath(cur->north, "south");
}
else if(cur->west != 0 && cur->west->visited == false)
{
cur->visited = true;
findPath(cur->north, "west");
}
else
{
cur->visited = false;
removeTail();
}
}
//Outputs the found path
void Graph::pathOut(ostream & s) const
{
if(path == 1)
{
Elem *p;
p = head->next;
while(p != 0)
{
s<<p->id<<"--> "<<p->last;
p= p->next;
}
}
else if(path == 0)
{
}
}
//Removes the last element in the chain
void Graph::removeTail()
{
Elem* temp = 0;
temp = tail;
tail = tail->back;
delete temp;
}
//Adds the element to the tail
void Graph::addTail(Node* n, string door)
{
if(head != 0)
{
Elem* temp = new Elem;
temp->id = n->id;
tail->next = temp;
tail->last = door;
temp->back = tail;
temp->next = 0;
tail = 0;
}
else
{
Elem *p = new Elem;
p->last = "";
p->back = 0;
p->next = 0;
head = p;
tail = p;
}
}
//Mutators
void Graph::setId(Node *n ,int x)
{
n->id = x;
}
void Graph::setVisited(Node *n, bool v)
{
n->visited = v;
}
//Elem Mutator
void Graph::seteId(Elem *e, int x)
{
e->id = x;
}
//Elem Accessor
int Graph::geteId(Elem *e)
{
return e->id;
}
//Accessors
int Graph::getId(Node *n)
{
return n-> id;
}
bool Graph::getVisited(Node *n)
{
return n->visited;
}
/*
//This is a graph with a very smart struct
//This is the main node that makes up the graph.
struct Node {
int id; //int id
Node *north; //north path node
Node *south; //south path node
Node *east; //east path node
Node *west; //went path node
bool visited; // visited bool
};
//this struct holds the path that is found.
struct Elem {
int id; //The id of the node
string last; //the door that it passed through
Elem* back; //back one path
Elem* next; //forward one path
};
Node* Start;
Node ** initArr;
Elem* head;
Elem* tail;
*/
//outputs using named operation
ostream & operator << (ostream &s, const Graph & v)
{
v.output(s);
return s;
}
The error is occurring on the find function.
In the cpp file, Node is not in global scope. It's nested inside Graph as such, you need to qualify it in a return type:
Graph::Node* Graph::find(int id){
// ...
}
Inside the function, you're in the scope of Graph again, as such you do not need to qualify it.
You have both Node and Element defined as structs inside the class Graph. It would be better to define them outside the class Graph. You can define a separate Node class and store the element struct as its private members. The error happens because Node is a private member of Graph, which can be accessed as Graph::Node. E.g. Graph::Node* find(...).