It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Could you guys check out my function somethingWrong(), and my overloading operators.
Sometimes when I run the function somethingwrong() I get "True" and sometimes "False".
I am not changing anything, why is this happening?
This is a Dijkstra algorithm graph I am working in.
Thank You
main.cpp:
#include <iostream>
#include <fstream>
#include "graph.h"
using namespace std;
int main(){
//
graph g;
g.addVertices();
//g.printAll();
g.addEdges();
cout << "Hello" << endl;
//g.printAdjList(5.74);
//g.DJAlgorithm();
g.somethingWrong();
return 0;
}
graph.h
#include <iostream>
#include <list>
#include <fstream>
#include "minHeap.h"
using namespace std;
class graph{
protected:
class vertex{
public:
int x;
int y;
double cost;
double weight;
vertex * parent;
list<vertex*> adjacencyList;
vertex(int xc, int yc, double c){
x = xc;
y = yc;
cost = c;
weight = -1;
parent = NULL;
}
// operator overloading
// dont know if to add =
vertex & vertex::operator=(vertex * z){
return *z;
}
bool vertex::operator==(vertex * z){
return (this->weight == z->weight);
}
bool vertex::operator!=(vertex * z){
return (this->weight != z->weight);
}
bool vertex::operator<=(vertex * z){
return (this->weight <= z->weight);
}
bool vertex::operator<(vertex * z){
return (this->weight < z->weight);
}
bool vertex::operator>=(vertex * z){
return (this->weight >= z->weight);
}
bool vertex::operator>(vertex * z){
return (this->weight > z->weight);
}
};
list<vertex*> vertexList;
int numOfVertices;
public:
int sX;
int sY;
int eX;
int eY;
graph(){
numOfVertices = 0;
}
void somethingWrong(){
vertex *dog = new vertex(0,0,0);
vertex * cat = new vertex(0,0,0);
dog->weight = 5;
cat->weight = 9;
if(dog < cat){
cout << "True" << endl;
}
else{
cout << "False" << endl;
}
}
void addVertices(){
ifstream inFile;
double w;
int countX = 1;
int countY = 1;
inFile.open("grid.txt");
if(!inFile){
cout << "Error opening file!" << endl;
return;
}
// get the coordinates of the starting and
// ending position
inFile >> sX;
inFile >> sY;
inFile >> eX;
inFile >> eY;
// get the grid of data
while(!inFile.eof()){
inFile >> w;
vertexList.push_back(new vertex(countX,countY,w));
numOfVertices++;
countX++;
if(inFile.peek() == '\n'){
countX = 1;
countY++;
}
}
}
void addEdges(){
for each(vertex * v in vertexList){
for each(vertex * w in vertexList){
if(((v->x == w->x) && (abs(v->y - w->y)) == 1) || ((v->y == w->y) && (abs(v->x - w->x) == 1))){
v->adjacencyList.push_back(w);
}
}
}
}
// prints all the grid, for verification purposes
void printAll(){
cout << sX << " " << sY << endl;
cout << eX << " " << eY << endl;
for each(vertex * v in vertexList){
cout << v->x << " " << v->y << " " << v->cost << endl;
}
}
// print a vertex's adjacency list
void printAdjList(double c){
for each(vertex * v in vertexList){
if(v->cost == c){
for each(vertex * w in v->adjacencyList){
cout << w->x << " " << w->y << " " << w->cost << endl;
}
return;
}
}
}
// problelm here
// prints the path from vertex x
void printPath(vertex * x){
if(x != NULL){
//cout << "sup" << endl;
printPath(x->parent);
cout << "(" << x->x << "," << x->y << ") weight: " << x->weight << endl;
}
}
void DJAlgorithm(){
// min Heap item
minHeap<vertex*> C(numOfVertices);
vertex * s;
vertex * x;
vertex * e;
// find required start and end vertices
for each(vertex * v in vertexList){
if(v->x == sX && v->y == sY){
s = v;
}
if(v->x == eX && v->y == eY){
e = v;
}
}
// set up all values
for each(vertex * v in vertexList){
v->weight = -1;
v->parent = NULL;
}
s->weight = 0;
// insert everything in to the queue/minHeap
for each (vertex * v in vertexList){
C.insert(v);
}
while(!C.empty()){
x = C.extractMin();
for each(vertex * v in x->adjacencyList){
// relax
// if not discovered
if(v->weight == -1){
v->weight = x->weight;
v->parent = x;
}
// if already discovered
else{
if(x->weight + v->cost < v->weight){
v->weight = x->weight + v->cost;
v->parent = x;
}
}
}
}
// print out the path back
printPath(e);
}
};
// min heap data structure
#include <iostream>
using namespace std;
template<class THING>
class minHeap
{
private:
//array to hold items
THING * items;
int n;
//return index of parent of i
int parent(int i)
{
return (i-1)/2;
}
//return index of left child of i
int lchild(int i)
{
return i*2 + 1;
}
//return index of right child of i
int rchild(int i)
{
return i*2 + 2;
}
//return index of smaller child
int minChild(int i)
{
if( lchild(i) >= n ) //a leaf!
return i;
else if( lchild(i) == (n-1) )
return lchild(i);
else if( items[lchild(i)] < items[rchild(i)] )
return lchild(i);
else
return rchild(i);
}
//bubble item at index current up tree
//until there's no more violation
void bubbleUp(int current)
{
// ignoring all these
if( current == 0 ) //the root! easy!
{
//do nothing, done, no violation, base case!
}
else if( items[current] >= items[parent(current)] ) //no violation
{
//do nothing!, done, go home, base case!
}
else
{
//step 1: swap current with parent
swap( items[current], items[parent(current)] );
//step 2: keep bubbling item up
bubbleUp( parent(current) );
}
}
void bubbleDown(int current)
{
if( lchild(current) >= n ) //current is a leaf....
{
//do nothing! base case!! party down!
}
else if( items[current] <= items[minChild(current)] ) //no violation..
{
//done!1 party down! base case
}
else
{
//step 1: swap with min child
int mchild = minChild(current);
swap( items[current], items[mchild] );
//step 2: continue bubbling down
bubbleDown(mchild);
}
}
public:
minHeap(int cap)
{
items = new THING[cap];
n=0;
}
//return true if heap is empty
bool empty()
{
if( n==0 )
return true;
else
return false;
}
//add item x to heap
void insert(THING x)
{
//step 1: add x to end of array
items[n] = x;
n++;
//step 2: bubble up!
bubbleUp(n-1);
}
//remove and return smallest item in heap
THING extractMin()
{
//step 1: store root item in output box
THING output = items[0];
//step 2: put last item at root
items[0] = items[n-1];
n--;
//step 3: bubble down!
bubbleDown(0);
return output;
}
};
vertex *dog = new vertex(0,0,0);
vertex *cat = new vertex(0,0,0);
if(dog < cat)
Compares two pointers and effectively the addresses. Comparing addresses does not make much sense as they can have any values.
You need to compare two objects:
if(*dog < *cat)
Ofcourse you also need to change the function prototype of the overloaded operator to take this in to account.
vertex & vertex::operator=(vertex * z)
That is an assignment operator that takes a left hand side of type vertex and a right hand side of type vextex*. The usual signature for operator= is:
vertex& operator=(const vertex& rhs);
The latter definition allows for assignment of one object to another object, while the former assigns a pointer to an object.
Related
I am creating a dynamic array class that holds polynomials. The problem I am having right now is when I run my code, once it hits the return statement in main it begins to call the destructor and begins to free the memory from each instance starting with C. It deletes C fine, but when it gets to B I get a heap corruption error. I have tried walking through the code, but I cannot see where the corruption is happening. Can anyone help me? The exact error it gives me is "CRT detected that the application wrote to memory after end of heap buffer."
*Edit: I am more than happy to get peoples recommendations to help make my code better, but remember this is for a class and has specific rules. I cannot use anything from STL. I love any criticism you can give me.
///////////////////////////Header/////////////////////////////
class Poly
{
friend std::ostream& operator<<(std::ostream& output, const Poly& pNomial);
public:
Poly();
Poly(const int& coeff, const int& degree = 0);
Poly(const Poly& copy);
~Poly();
void setCoeff(const int& coeff, const int& degree);
bool isEmpty()const;
Poly& operator=(const Poly& pNomial);
private:
int* coeffs;
int highestDegree;
};
///////////////////////////CPP////////////////////////
#include "poly.h"
Poly::Poly()
{
highestDegree = 0;
coeffs = new int[highestDegree+1]();
}
Poly::Poly(const int & coeff, const int & degree)
{
if (degree >= 0)
{
highestDegree = degree;
coeffs = new int[highestDegree + 1]();
coeffs[degree] = coeff;
}
else
{
highestDegree = 0;
coeffs = new int[highestDegree + 1]();
}
}
Poly::Poly(const Poly& copy)
{
highestDegree = copy.highestDegree;
coeffs = new int[highestDegree + 1]();
for (int i = 0; i < copy.highestDegree + 1; i++)
{
coeffs[i] = copy.coeffs[i];
}
}
Poly::~Poly()
{
delete[] coeffs;
}
void Poly::setCoeff(const int& coeff, const int& degree)
{
if (degree > this->highestDegree)
{
Poly temp = *this;
delete[] this->coeffs;
this->highestDegree = degree;
this->coeffs = new int[highestDegree]();
for (int i = 0; i < temp.highestDegree + 1; i++)
{
this->coeffs[i] = temp.coeffs[i];
}
}
if (degree >= 0)
{
this->coeffs[degree] = coeff;
}
}
bool Poly::isEmpty()const
{
bool check = true;
for (int i = 0; i < highestDegree + 1 && check; i++)
{
if (coeffs[i] != 0)
{
check = false;
}
}
return check;
}
Poly & Poly::operator=(const Poly& pNomial)
{
if (this != &pNomial)
{
delete[] this->coeffs;
this->highestDegree = pNomial.highestDegree;
this->coeffs = new int[this->highestDegree + 1]();
for (int i = 0; i < pNomial.highestDegree + 1; i++)
{
this->coeffs[i] = pNomial.coeffs[i];
}
}
return *this;
}
std::ostream& operator<<(std::ostream& output, const Poly& poly)
{
if (!poly.isEmpty())
{
for (int i = poly.highestDegree; i >= 0; i--)
{
if (i == 1 && poly.coeffs[i] != 0)
{
if (poly.coeffs[i] >= 1)
{
output << " +" << poly.coeffs[i] << "x";
}
else
{
output << " " << poly.coeffs[i] << "x";
}
}
else if (i == 0 && poly.coeffs[i] != 0)
{
if (poly.coeffs[i] >= 1)
{
output << " +" << poly.coeffs[i];
}
else
{
output << " " << poly.coeffs[i];
}
}
else if (poly.coeffs[i] != 0)
{
if (poly.coeffs[i] >= 1)
{
output << " +" << poly.coeffs[i] << "x^" << i;
}
else
{
output << " " << poly.coeffs[i] << "x^" << i;
}
}
}
}
else
{
output << " 0";
}
return output;
}``
/////////////////////////////////Main/////////////////////////
#include "poly.h"
#include <iostream>
int main()
{
Poly A, B(5, 7), C(2);
B.setCoeff(2, 10);
B.setCoeff(1, 3);
B.setCoeff(5, 4);
std::cout << A << std::endl;
std::cout << B << std::endl;
std::cout << C << std::endl;
return 0;
}
I must say, that I agree with comments and you should seriously look into proper lifetime management of resources you use in the Poly class.
To answer the problem you're facing now have a look at the setCoeff() function.
this->coeffs = new int[highestDegree]();
should be changed to,
this->coeffs = new int[highestDegree + 1]();
With your current implementation, you allocate the array with highestDegree and in your for loop you access temp.coeffs[highestDegree] which is out of bounds access i.e. you loop till i < temp.highestDegree + 1.
I'm not too sure if questions of this sort is allowed on stackoverflow but here it goes. I finished up this assignment to calculate reverse polish expressions with a small set of operators. All the tests passed and I have already submitted the assignment. I was wondering if you guys had any suggestions where I could improve on the code that could be applied to my future assignments/projects.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class TheStack
{
public:
void push(double d1);
double pop();
int getNodeTracker();
private:
struct Node
{
double data;
Node* next;
};
Node* bottom = NULL;
Node* top = NULL;
Node* newP = NULL;
int nodeTracker = 0;
};
void TheStack::push(double d1)
{
newP = new Node;
newP->data = d1;
newP->next = NULL;
if (bottom == NULL)
{
bottom = top = newP;
top->next = NULL;
}
else
{
newP->next = top;
top = newP;
}
nodeTracker += 1;
}
double TheStack::pop()
{
Node* tempP;
double tempD;
if (top == NULL)
{
cout << "The stack is empty." << endl;
}
else
{
tempP = top;
tempD = tempP->data;
top = top->next;
delete(tempP);
nodeTracker -= 1;
return(tempD);
}
}
int TheStack::getNodeTracker()
{
return nodeTracker;
}
bool isOperand(string s1);
bool isOperator(string s1);
double operate(string s1, double d1, double d2);
int processor(string str);
bool validString(string str);
int main()
{
// getting user input
string str;
getline(cin, str);
// input loop
while (str != "0")
{
processor(str);
cout << endl;
getline(cin, str);
}
// end program
return 0;
}
bool isOperand(string s1)
{
try
{
stod(s1);
}
catch (...)
{
return false;
}
return true;
}
bool isOperator(string s1)
{
string validOps[4] = { "+", "-", "*", "/" };
for (int i = 0; i < 4; i++)
{
if (s1 == validOps[i])
{
return true;
}
}
return false;
}
double operate(string s1, double d1, double d2)
{
char op = s1[0];
switch (op)
{
case '+':
return d1 + d2;
case '-':
return d1 - d2;
case '*':
return d1 * d2;
case '/':
return d1 / d2;
}
}
bool validString(string str)
{
for (int i = str.size()-1; i >= 0; i--)
{
if (str[i] == '=')
{
return true;
}
}
return false;
}
int processor(string str)
{
TheStack stacklist;
istringstream iss(str);
string streamVar;
iss >> streamVar;
// checks if expression has = sign
if (!validString(str))
{
cout << "Error: Please input valid expression." << endl;
return -1;
}
// builds and operates upon stack
while (streamVar != "=")
{
if (isOperand(streamVar))
{
stacklist.push(stod(streamVar));
}
else if (isOperator(streamVar))
{
if (stacklist.getNodeTracker() > 1)
{
double d2 = stacklist.pop();
double d1 = stacklist.pop();
if (streamVar == "/" && d2 == 0)
{
cout << "Error: Division by 0." << endl;
return -1;
}
double result = operate(streamVar, d1, d2);
stacklist.push(result);
}
else
{
cout << "Error: Too many operators." << endl;
return -1;
}
}
iss >> streamVar;
}
// operand error case
if (stacklist.getNodeTracker() > 1)
{
cout << "Error: Too many operands." << endl;
return -1;
}
// output
cout << stacklist.pop() << endl;
return 0;
}
I am writing a priority queue with a max heap structure as an assignment for school. I can either write it as an array or I can use a vector. I chose a vector. So the assignment is this, the user chooses options from a menu where he either wants to add,print, or view the elements. When the user chooses to add he gets ask who wants to be added, the instructor, student, or TA. He can enter i,I,t,T,S,s. The instructor having the highest priority where if the user chooses the option to print and there is an instructor in the queue he gets to go first. The TA having the second highest priority where if there is a TA and a student in the queue, the TA goes first. If there is is more than one instructor than the queue acts as a normal queue. I have written most of it, or tried. I got my max heap implementation from my textbook since they provide one. Now the problem is this, when I have more than one item in the priority queue and I choose to print, it crashes and gives me a vector subscript out of range exception. I been trying to fix it and no luck. Also, when I try to print the elements in the queue or print them, it needs to say the job# with the name of the person. Can someone help me find a way to implement that.
#pragma once
#include <vector>
struct Heap
{
std::vector<int> m_elements;
void ReHeapDown(int, int);
void ReHeapUp(int, int);
void Swap(int& a, int& b);
};
#include "heap.h"
void Heap::ReHeapDown(int index, int bottom)
{
int maxChild, rightChild, leftChild;
leftChild = index * 2 + 1;
rightChild = index * 2 + 2;
if (leftChild <= bottom)
{
if (leftChild == bottom)
maxChild = leftChild;
else
{
if (m_elements[leftChild] <= m_elements[rightChild])
maxChild = rightChild;
else
maxChild = leftChild;
}
if (m_elements[index] < m_elements[maxChild])
{
Swap(m_elements[index], m_elements[maxChild]);
ReHeapDown(maxChild, bottom);
}
}
}
void Heap::ReHeapUp(int index, int bottom)
{
int parent;
if (bottom > index)
{
parent = (bottom - 1) / 2;
if (m_elements[parent] < m_elements[bottom])
{
Swap(m_elements[parent], m_elements[bottom]);
ReHeapUp(index, parent);
}
}
}
void Heap::Swap(int& a, int& b)
{
int temp;
temp = a;
a = b;
b = temp;
}
#include <iostream>
#include "heap.h"
#pragma once
class PQTYPE
{
private:
Heap m_Items;
public:
bool isEmpty() const;
void Enqueue(int, std::string);
void Dequeue(int, std::string);
void printElements();
};
#include "pqtype.h"
bool PQTYPE::isEmpty() const
{
return m_Items.m_elements.empty();
}
void PQTYPE::Enqueue(int newItem, std::string lName)
{
if (lName == "Student")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (lName == "TA")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (lName == "Instructor")
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::Dequeue(int item, std::string lName)
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
m_Items.m_elements[0] = m_Items.m_elements.back();
std::cout << "Now printing Job#" << m_Items.m_elements[item - 1] << " " << lName.c_str() << std::endl;
m_Items.m_elements.pop_back();
m_Items.ReHeapDown(0, item - 1);
}
}
void PQTYPE::printElements()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
for (int i = 0; i < m_Items.m_elements.size(); i++)
{
std::cout << "Job#" << m_Items.m_elements[i] << std::endl;
}
}
}
#include"pqtype.h"
struct Person
{
int m_priority;
std::string m_name;
Person()
{
m_priority = 0;
m_name = " ";
}
};
int showMenu();
void addJobs(PQTYPE&, Person&);
void printJobs(PQTYPE&, Person&);
void viewJobs(PQTYPE&);
int main()
{
int option;
Person p;
PQTYPE pq;
do
{
option = showMenu();
switch (option)
{
case 1: addJobs(pq, p);
break;
case 2: printJobs(pq, p);
break;
case 3: viewJobs(pq);
break;
case 4:
break;
default: std::cout << "Wrong input\n";
break;
}
} while (option != 4);
return 0;
}
int showMenu()
{
int choice;
std::cout << " 1.)Add Job\n";
std::cout << " 2.)Print Job\n";
std::cout << " 3.)View Jobs\n";
std::cout << " 4.)Exit\n";
std::cout << " Enter Choice: ";
std::cin >> choice;
return choice;
}
void addJobs(PQTYPE& pq, Person& per)
{
char jobChoice;
std::cout << "Who is the job for ( Instructor(i or I), TA(t or T), Student(s or S) :";
std::cin >> jobChoice;
if (jobChoice == 'S' || jobChoice == 's')
{
per.m_priority++;
per.m_name = "Student";
pq.Enqueue(per.m_priority, per.m_name);
}
else if (jobChoice == 'T' || jobChoice == 't')
{
per.m_priority++;
per.m_name = "TA";
pq.Enqueue(per.m_priority, per.m_name);
}
if (jobChoice == 'I' || jobChoice == 'i')
{
per.m_priority++;
per.m_name = "Instructor";
pq.Enqueue(per.m_priority, per.m_name);
}
}
void printJobs(PQTYPE& pq, Person& p)
{
pq.Dequeue(p.m_priority, p.m_name);
}
void viewJobs(PQTYPE& pq)
{
pq.printElements();
}
In your original code the index used inside Dequeue() for accessing the vector doesn't seem to be initialised in the right way. Let's assume that you have added two entries to your list. In this case the value of P.m_priority inside your main() is 2. Now you're calling printJobs() for the first time. printJobs() calls pq.Dequeue(p.m_priority, p.m_name), so Dequeue() gets p.m_priority as its parameter item. Keep in mind that item has the value 2.
m_Items.m_elements[0] = m_Items.m_elements.back();
std::cout << "Now printing Job#" << m_Items.m_elements[item - 1] << " " << lName.c_str() << std::endl;
m_Items.m_elements.pop_back();
You're accessing your std::vector using an index of item - 1. This works for the first time, as there are two elements in your list. In this call, there is also a pop_back() done on your list, which decreases its size by one. The next time you call printJobs(), the given parameter item won't have changed, it still has the value 2. When you access your Itemlist, there is no longer an index of 1, and an subscript out of range exception will be thrown.
There were no fixed priorities assigned to the three entry types in your original version, so I added these (see addJobs() ).
So a possible solution to store the person's name could look like this:
struct Person
{
int m_priority;
std::string m_name;
Person()
{
m_priority = 0;
m_name = " ";
}
};
struct Heap
{
std::vector<Person> m_elements;
void ReHeapDown(int, int);
void ReHeapUp(int, int);
void Swap(Person& a, Person& b);
};
void Heap::ReHeapDown(int index, int bottom)
{
int maxChild, rightChild, leftChild;
leftChild = index * 2 + 1;
rightChild = index * 2 + 2;
if (leftChild <= bottom)
{
if (leftChild == bottom)
maxChild = leftChild;
else
{
if (m_elements[leftChild].m_priority <= m_elements[rightChild].m_priority)
maxChild = rightChild;
else
maxChild = leftChild;
}
if (m_elements[index].m_priority < m_elements[maxChild].m_priority)
{
Swap(m_elements[index], m_elements[maxChild]);
ReHeapDown(maxChild, bottom);
}
}
}
void Heap::ReHeapUp(int index, int bottom)
{
int parent;
if (bottom > index)
{
parent = (bottom - 1) / 2;
if (m_elements[parent].m_priority < m_elements[bottom].m_priority)
{
Swap(m_elements[parent], m_elements[bottom]);
ReHeapUp(index, parent);
}
}
}
void Heap::Swap(Person& a, Person& b)
{
Person temp;
temp = a;
a = b;
b = temp;
}
#include <iostream>
class PQTYPE
{
private:
Heap m_Items;
public:
bool isEmpty() const;
void Enqueue(Person);
void Dequeue();
void printElements();
};
bool PQTYPE::isEmpty() const
{
return m_Items.m_elements.empty();
}
void PQTYPE::Enqueue(Person newItem)
{
if (!newItem.m_name.compare("Student"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (!newItem.m_name.compare("TA"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
else if (!newItem.m_name.compare("Instructor"))
{
m_Items.m_elements.push_back(newItem);
m_Items.ReHeapUp(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::Dequeue()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
Person front = m_Items.m_elements.front();
std::cout << "Now printing Job#" << front.m_priority << " " << front.m_name.c_str() << std::endl;
m_Items.m_elements.erase(m_Items.m_elements.begin());
m_Items.ReHeapDown(0, m_Items.m_elements.size() - 1);
}
}
void PQTYPE::printElements()
{
if (isEmpty())
std::cout << "No jobs to print\n";
else
{
for (int i = 0; i < m_Items.m_elements.size(); i++)
{
std::cout << "Job#" << m_Items.m_elements[i].m_priority << " " << m_Items.m_elements[i].m_name.c_str() << std::endl;
}
}
}
int showMenu();
void addJobs(PQTYPE&, Person&);
void printJobs(PQTYPE&, Person&);
void viewJobs(PQTYPE&);
int showMenu()
{
int choice;
std::cout << " 1.)Add Job\n";
std::cout << " 2.)Print Job\n";
std::cout << " 3.)View Jobs\n";
std::cout << " 4.)Exit\n";
std::cout << " Enter Choice: ";
std::cin >> choice;
return choice;
}
void addJobs(PQTYPE& pq, Person& per)
{
char jobChoice;
std::cout << "Who is the job for ( Instructor(i or I), TA(t or T), Student(s or S) :";
std::cin >> jobChoice;
if (jobChoice == 'S' || jobChoice == 's')
{
per.m_priority = 0;
per.m_name = "Student";
pq.Enqueue(per);
}
else if (jobChoice == 'T' || jobChoice == 't')
{
per.m_priority = 1;
per.m_name = "TA";
pq.Enqueue(per);
}
if (jobChoice == 'I' || jobChoice == 'i')
{
per.m_priority = 2;
per.m_name = "Instructor";
pq.Enqueue(per);
}
}
void printJobs(PQTYPE& pq)
{
pq.Dequeue();
}
void viewJobs(PQTYPE& pq)
{
pq.printElements();
}
int main()
int option;
Person p;
PQTYPE pq;
do
{
option = showMenu();
switch (option)
{
case 1: addJobs(pq, p);
break;
case 2: printJobs(pq);
break;
case 3: viewJobs(pq);
break;
case 4:
break;
default: std::cout << "Wrong input\n";
break;
}
} while (option != 4);
return 0
}
Are you sure that the methods ReHeapUp and ReHeapDown meet your requirements? And shouldn't there be a distinction between job number and priority?
I am attempting to implement the Tower of Hanoi iterative solution in c++ as noted in Wikepedia
Simpler statement of iterative solution
Alternating between the smallest and the next-smallest disks, follow the steps for the appropriate case:
For an even number of disks:
*make the legal move between pegs A and B*
*make the legal move between pegs A and C*
*make the legal move between pegs B and C*
*repeat until complete*
For an odd number of disks:
*make the legal move between pegs A and C*
*make the legal move between pegs A and B*
*make the legal move between pegs C and B*
*repeat until complete*
In each case, a total of 2n-1 moves are made.
The code I have written thus far is
#include <iostream>
#include <list>
const int SIZE = 5;
int pCount = 1;
using namespace std;
list<int> *lhs;
list<int> *mid;
list<int> *rhs;
void initTower(int size);
void printPeg(list<int> p);
bool printTower();
bool isEven(list<int> l);
bool move(list<int> *from, list<int> *to);
int main() {
lhs = new list<int>;
mid = new list<int>;
rhs = new list<int>;
initTower(SIZE);
printTower();
bool run = true;
while (run) {
int n = SIZE;
if (n % 2 == 0) // even
{
move(lhs,mid);
move(lhs,rhs);
move(mid,rhs);
}else{
move(lhs,rhs);
move(lhs,mid);
move(rhs,mid);
}
if (rhs->size() == SIZE) {
run = false;
}
}
return 0;
}
bool isEven(list<int> l) {
return l.size() % 2 == 0;
}
void initTower(int size) {
while (size--)
lhs->push_back(size + 1);
}
void printPeg(list<int> p) {
if (p.empty()) {
cout << "empty" << endl;
} else {
for (int i: p)
cout << i << " ";
cout << endl;
}
}
bool printTower() {
cout << "==============" << endl;
cout << "=====top=======" << pCount++ << endl;
printPeg(*lhs);
printPeg(*mid);
printPeg(*rhs);
cout << "==============" << endl << endl;
return true;
}
bool move(list<int> *from, list<int> *to) {
bool vailidMove = false;
int fVal = 0;
int toVal = 0;
if (!from->empty())
fVal = from->back();
if (!to->empty())
toVal = to->back();
if ((fVal < toVal || toVal == 0) && (fVal > 0 && fVal != 0)) {
from->pop_back();
to->push_back(fVal);
vailidMove = true;
printTower();
}
return vailidMove;
}
my output to the above program is.
==============
=====top=======1
5 4 3 2 1
empty
empty
==============
==============
=====top=======2
5 4 3 2
empty
1
==============
==============
=====top=======3
5 4 3
2
1
==============
==============
=====top=======4
5 4 3
2 1
empty
==============
==============
=====top=======5
5 4
2 1
3
==============
What am I overlooking? Any advise is helpful.
I added one condition in your move function to move poles if fVal > toVal (or you would stop instead of finishing the algorithm).
I alternated the source and destination half the time, as this is said in the wiki article you were referring to.
Alternating between the smallest and the next-smallest disks
I also changed the pCount initialization to 0 instead of 1 as the first print only list the starting tower and is not an operation. But you may put 1 again if that if what you wanted.
PS: I tested this code and it works perfectly fine, giving 2^n-1 operations like it is supposed to.
#include <iostream>
#include <list>
const int SIZE = 12;
int pCount = 0;
using namespace std;
list<int> *lhs;
list<int> *mid;
list<int> *rhs;
void initTower(int size);
void printPeg(list<int> p);
bool printTower();
bool isEven(list<int> l);
bool move(list<int> *from, list<int> *to);
int main() {
lhs = new list<int>;
mid = new list<int>;
rhs = new list<int>;
initTower(SIZE);
printTower();
bool run = true;
bool lowest = false;
while (run) {
lowest = !lowest;
int n = SIZE;
if (n % 2 == 0) // even
{
if (lowest){
move(lhs,mid);
if (rhs->size() == SIZE) {
break;
}
move(lhs,rhs);
move(mid,rhs);
}else{
move(mid,lhs);
if (rhs->size() == SIZE) {
break;
}
move(rhs,lhs);
move(rhs,mid);
}
}else{
if (lowest){
move(lhs,rhs);
move(lhs,mid);
if (rhs->size() == SIZE) {
break;
}
move(mid,rhs);
}else{
move(rhs,lhs);
move(mid,lhs);
if (rhs->size() == SIZE) {
break;
}
move(rhs,mid);
}
}
lowest = !lowest;
}
return 0;
}
bool isEven(list<int> l) {
return l.size() % 2 == 0;
}
void initTower(int size) {
while (size--)
lhs->push_back(size + 1);
}
void printPeg(list<int> p) {
if (p.empty()) {
cout << "empty" << endl;
} else {
for (int i: p)
cout << i << " ";
cout << endl;
}
}
bool printTower() {
cout << "==============" << endl;
cout << "=====top=======" << pCount++ << endl;
printPeg(*lhs);
printPeg(*mid);
printPeg(*rhs);
cout << "==============" << endl << endl;
return true;
}
bool move(list<int> *from, list<int> *to) {
bool vailidMove = false;
int fVal = 0;
int toVal = 0;
if (!from->empty())
fVal = from->back();
if (!to->empty())
toVal = to->back();
if ((fVal < toVal || toVal == 0) && fVal > 0) {
from->pop_back();
to->push_back(fVal);
vailidMove = true;
printTower();
}else if ((fVal > toVal || fVal == 0) && (toVal > 0 && toVal != 0)) {
from->push_back(toVal);
to->pop_back();
vailidMove = true;
printTower();
}
return vailidMove;
}
i have a c2280 error in c++ and i don't know how to solve it.
here is the code:
#include <iostream>
#include <queue>
#include <deque>
#include "State.h"
#include <assert.h>
#define MAXIMUM_NUMBER_OF_STATES 1000
#define DELTA_Q 0.1
using namespace std;
class RRT
{
private:
float inc_dist;
State start;
State goal;
deque<State> states = deque<State>();
bool goal_is_reached = false;
float RRT::random(float min, float max){
// check if min is less than max , if not then exception is thrown
assert(max >= min);
float range = max - min;
float random;
random = rand() / RAND_MAX;
return (random * (range)) + min;
}
State RRT::randomState(State current_state){
State state = State();
srand(time(0));
while (inStates(state))
{
state.x = random(min(current_state.x, goal.x), max(current_state.x, goal.x));
state.y = random(min(current_state.y, goal.y), max(current_state.y, goal.y));
state.z = random(min(current_state.z, goal.z), max(current_state.z, goal.z));
}
return state;
}
bool RRT::inStates(State state){
for (int i = 0; i < states.size(); i++){
if (states.at(i).x == state.x && states.at(i).y == state.y && states.at(i).z==state.z)
return true;
}
return false;
}
bool RRT::goalTest(State state){
if (state.x == goal.x && state.y == goal.y && state.z == goal.z){
return true;
}
else
return false;
}
void RRT::Successor(State state){
State temp3;
State temp2;
cout <<endl<< "was"<<endl;
if (goalTest(state) || states.size() == MAXIMUM_NUMBER_OF_STATES){
return;
}
getNearistNeighbor(temp3=randomState(state));
cout << "random x: " << temp3.x << " random y: " << temp3.y << " random z: " << temp3.z << endl;
temp2 = State(temp3);
temp2.setFather(state);
states.push_back(temp2);
states.back().setFather(state);
Successor(states.back());
return;
}
State RRT::getNearistNeighbor(State sub_goal_state){
float min_dist = 0, temp;
State desired_state;
for (int i = 0; i < states.size(); i++){
temp = distanceBetweenTwoStates(states.at(i), sub_goal_state);
if (temp < min_dist){
min_dist = temp;
desired_state = State(states.at(i));
}
}
return desired_state;
}
void RRT::generatePath(State state){
cout << endl << "1" << endl;
if (!state.checkIfNull()){
cout << endl << "end" << endl;
return;
cout << endl << "2" << endl;
generatePath(*state.getFather().get());
path.push_back(state);
}
cout << endl << "2" << endl;
generatePath(*state.getFather().get());
path.push_back(state);
return;
}
float RRT::distanceBetweenTwoStates(State state1, State state2){
float x_distance, y_distance, z_distance;
x_distance = sqrt(pow((state1.x - state2.x), 2));
y_distance = sqrt(pow((state1.y - state2.y), 2));
z_distance = sqrt(pow((state1.z - state2.z), 2));
return x_distance + y_distance + z_distance;
}
public:
deque<State> path = deque<State>();
deque<float*> xyzs = deque<float*>();
RRT::RRT(){
}
RRT::RRT(float* starting_point, float* goal_point)
{
start = State(starting_point);
goal= State(goal_point);
states.push_back(start);
}
deque<float*> RRT::getPath(){
Successor(start);
for (int i = 0; i < states.size();i++)
{
if (goalTest(states.at(i))){
goal_is_reached = true;
path.push_back(states.at(i));
break;
}
}
if (goal_is_reached==false){
path.push_back(getNearistNeighbor(goal));
}
State state;
state=State(path.at(0));
path.pop_front();
cout << endl << "x: " << state.x;
cout << endl << "y: " << state.y;
cout << endl << "z: " << state.z << endl;
generatePath(state);
convertToXYZ();
return xyzs;
}
void convertToXYZ(){
State temp;
float* xyz = new float[3];
for (int i = 0; i < path.size(); i++){
temp = path.at(i);
xyz[0] = temp.x;
xyz[1] = temp.y;
xyz[3] = temp.z;
xyzs.push_back(xyz);
}
}
};
here is the code for State.h:
#include <memory>
using namespace std;
class State
{
private:
unique_ptr<State> father;
public:
float x;
float y;
float z;
State(float *xyz){
x = 0;
y = 0;
z = 0;
father = NULL;
}
State(){
x = 0;
y = 0;
z = 0;
father = NULL;
}
State(State& state) : father(new State(*state.father)), x(state.x), y(state.y), z(state.z) {}
State(unique_ptr<State>& state) : father(new State(*state.get())){}
void setFather(State& state){
father.reset(new State(state));
}
unique_ptr<State> getFather(){
unique_ptr<State> temp(new State(*this));
return temp;
}
bool checkIfNull(){
if (father){
return true;
}
else
return false;
}
};
i have been trying to solve this problem but i have not succeed so i need your help guys please help me in solving this.
thanks in advance.
here is the error:
Error 8 error C2280: 'std::unique_ptr<State,std::default_delete<_Ty>> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function c:\users\userr\documents\visual studio 2013\projects\devo controller\devo controller\rrt.h 186 1 Devo Controller
again thanks in advance.
unique_ptr<State> getFather(){
unique_ptr<State> temp(new State(*this));
return temp;
}
you can't return unique_ptr . returning a value from function means using the copy constructor. the copy constructor is disabled for unique_ptr. why? because you can't copy a unique_ptr , it's unique! you need to use shared_ptr if many pointers are to point to a specific object. the same goes for the assignment operator ( = ) .
PS. I think it's deprecated to explicitly assign object memory addres to unique_ptr (with new) , the new standard forces you to use std::make_unique in order to assign something to unique_ptr.
also, try googling your error first, you'll be surprised how many answers there are out there