so I'm making a C++ Checkers like game for my AI class. I've run into a bit of a hiccup that's driving me insane, each opponent piece is a struct that contains a direction: bool left; bool right; When I try and change one of the values to be true, it doesn't seem to change. It seems to be a scope issue but i don't know why, I've followed it through using vs debug tool. Here's some of the code:
typedef struct {
int pos;
int num;
bool left;
bool right;
}opp;
int scoreOp(opp o){
if (scoreMoveOp(o.pos + 7) == 10){
o.left = true;
return 10;
}
else if (scoreMoveOp(o.pos + 9) == 10){
o.right = true;
return 10;
}
int scoreOp(opp o){
if (scoreMoveOp(o.pos + 7) == 10){ //scoreMoveOp essentially returns ten.
o.left = true;
return 10;
}
else if (scoreMoveOp(o.pos + 9) == 10){
o.right = true;
return 10;
}
and is all is called:
void checkOPPListForX(){
for (int i = 0; i < O1Moves.size(); i++){
if (X == O1Moves[i].second){
//cout << "O1 has it, and its score is: " << scoreOp(O1) << endl;
O1Score = scoreOp(O1);
O1Check = true;
}
else O1Check = false;
}
checkOPPListForX();
if (O1Score > O2Score && O1Score > O3Score && O1Score > O4Score){
//move O1;
//O1.pos
if (O1.left)
O1.pos = O1.pos + 7;
else if (O1.right)
O1.pos = O1.pos + 9;
}
You're passing the variable to the scoreOp function by value, which means that the function gets a copy. And modifying a copy will of course not modify the original.
You need to pass the argument by reference instead:
int scoreOp(opp& o){ ... }
// ^
// |
// Note ampersand here, which means that the argument is passed by reference
The easiest way is to put your function inside the struct :
typedef struct {
int pos;
int num;
bool left;
bool right;
int scoreOp() {.....}
}opp;
and then you can call it with opp.ScoreOp()
This solution is if you're not too comfortable passing by reference
Related
I have made two classes: stack1 and stack2 and defined my own stack operations of push(), pop(), isempty() and isfull(). I am trying to calculate a postfix expression from an input. I have made another class called operation that is a child of stack1 and stack2, so I can access the functions of push(),pop(), etc.. within operation. I have a function within operation called operate() that does the dirty work on the stacks. Within this function I have a while loop that depends on stack1 not being empty until the operation is complete; HOWEVER, when I step through this function top1, where stack1 is pointing to, has been reset to 0. Is there a way to overcome this/am I doing something wrong? This is the first time I am using classes and such, so I am not sure of the ins and outs.
Here are the definitions of my classes:
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
void push1(int data)
{
if (is_full1());
else
{
num1[top1] = data;
top1++;
}
}
int pop1(void)
{
if(is_empty1());
else
{
top1--;
return num1[top1];
}
}
int is_empty1(void)
{
if(top1 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full1(void)
{
if(top1 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
} };
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
void push2(int data)
{
if (is_full2());
else
{
num2[top2] = data;
top2++;
}
}
int pop2(void)
{
if(is_empty2());
else
{
top2--;
return num2[top2];
}
}
int is_empty2(void)
{
if(top2 == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full2(void)
{
if(top2 == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
} };
class operation: public stack2, public stack1 {
private:
int answer;
int a;
int b;
int num_cnt;
int ans;
int from_st1;
int from_st2;
public:
int c;
int oper(void)
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
c = 0;
stack1 st1;
stack2 st2;
while(!st1.is_empty1())
{
from_st1 = st1.pop1();
if(from_st1 == plus)
{
st2.push2(from_st1);
}else if(from_st1 == minus)
{
st2.push2(from_st1);
}else if(from_st1 == mult)
{
st2.push2(from_st1);
}else if (from_st1 == divide)
{
st2.push2(from_st1);
}else if(num_cnt == 1)
{
num_cnt = 0;
if(ans == 0)
{
answer = b;
ans++;
}
a = from_st1;
from_st2 = st2.pop2();
if(from_st2 == plus)
{
c = a+answer;
}else if(from_st2 == minus)
{
c = a-answer;
}else if(from_st2 == mult)
{
c = a*answer;
}else if(from_st2 == divide)
{
c = a/answer;
}
}else
{
b = from_st1;
}
num_cnt++;
}
return c;
}
operation()
{
answer = 0;
a = 0;
b = 0;
num_cnt = 0;
ans = 0;
from_st1 = 0;
from_st2 = 0;
} };
I think that the "problem" is with the line:
stack1 st1;
stack2 st2;
This will call the default constructor and set the value of the variables top1 and top2 as zero.
A workaround to this would be to initialise these variables with some positive non-zero value.
Hence the code would look something like(focusing only on the changed parts):
class stack1 {
private:
int num1[SIZE/2]; int top1;
public:
.....
stack1()
{
top1 = 0; num1[SIZE/2] = {0};
}
stack1(int top1)
{this.top1 = top1;}
};
class stack2 {
private:
int num2[SIZE/2]; int top2; public:
public:
.....
stack2()
{
top2 = 0; num2[SIZE/2] = {0};
}
stack2(int top2)
{this.top2 = top2;}
};
class operation: public stack2, public stack1 {
.....
public:
int c;
int oper(void)
{
.....
//just an example, can be declared explicitly as well
stack1 st1(5);
stack2 st2(7);
.....
Also, I would advice you to make your code a bit more readable(for instance the presence of 3-liner {} in if cases spanning only a single line). It is just unnecessary consumption of space.
And finally, if the "redefinition" of parent class' variables means the variables re-asserting some value on being inherited, they don't, unless you specify explicitly(such as using a constructor in our case to assign different values to top1 and top2). The inherited class will get a copy of the state of the parent class*.
*meaning they cannot be changed directly by the inherited class. For example if you would've done: int top1=5; initially then top1 would've been 5 until it were to be redefined again somewhere(such as using a constructor)
I take from the problem statement you are trying to build a basic calculator with four operators and need basic expression evaluation done using stack.
Say you have an expression: a+b-cd/e
looks like this in stack: TOP e->/->d->->c->-->b->+->a EMPTY
And this track needs to be evaluated.
Based on these.. you may be looking for something like below:
class stack {
private:
int num[SIZE];
int top;
public:
void push(int data)
{
if (is_full1());
else
{
num[top] = data;
top++;
}
}
int pop(void)
{
if(is_empty());
else
{
top--;
return num[top];
}
}
int is_empty(void)
{
if(top == 0)
{
return 1;
}else
{
return 0;
}
}
int is_full(void)
{
if(top == SIZE)
{
return 1;
}else
{
return 0;
}
}
stack()
{
top = 0; num[SIZE] = {0};
}
};
class operation {
private:
int answer;
int op1;
int op;
boolean isOperator(int val) {
boolen retVal = false;;
if (val == plus ||
val == minus ||
val == divide ||
val == mult) {
retVal = true;
}
else {
retVal = false;
}
return retVal;
}
public:
int oper(stack st1)
{
int from_st1 = 0;
while(!st1.is_empty())
{
from_st1 = st1.pop();
if(isOperator(from_st1))
{
op = from_st1;
}
else if(answer != 0)
{
op1 = from_st1;
if(op == plus)
{
answer = op1 + answer;
}else if(op == minus)
{
answer = op1 - answer;
}else if(op == mult)
{
answer = op1 * answer;
}else if(op == divide)
{
answer = op1 / answer;
}
}
else
{
answer = from_st1;
}
}
return answer;
}
operation()
{
answer = 0;
op1 = 0;
op = 0;
}
};
Note: You can do all evaluation with one stack don't need two stacks. Your operands can not equal to integer values for +, -, * and / for this assignment. You have a valid expression input into stack in main() code.
I have method of class Stack, which compares 2 objects of this class:
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
and uses the method of class Time:
bool comparison(Time &time) {
if ((this->hours == time.hours) && (this->minutes == time.minutes) && (this->seconds == time.seconds))
return true;
return false;
When I try to use this comman in main:
bool temp = stack3.comparison(stack4);
MVS underlines |stack4| and shows me the error:
a reference of type "Time &"(non-const qualified) cannot be initialized with a value of type Stack<Time>
How could I handle this problem?
Thanks for your answers :)
There is class Stack:
class Stack {
private:
T *stackPr;
int size;
int top;
public:
//----------------CONSTRUCTORS-----------------
Stack(int n) {
if (n > 0)
size = n;
else
size = 10;
stackPr = new T[size];
top = -1;
}
Stack() {
size = 10;
stackPr = new T[size];
top = -1;
}
Stack(Stack &stack) {
stackPr = new T[stack.size];
size = stack.size;
top = stack.top;
for (int i = 0; i < size; i++)
stackPr[i] = stack.stackPr[i];
}
Stack(T *objs, int sizeMass) {
size = sizeMass;
stackPr = new T[size];
for (int i = 0; i < sizeMass; i++) {
this->push(objs[i]);
}
}
//----------------DESTRUCTOR-------------------
~Stack() {
delete[] stackPr;
}
//-----------------METHODS---------------------
//Add element to stack
void push(T &element) {
if (top == size - 1)
cout << "\nThere's no more place!!!\n";
else {
top++;
stackPr[top] = element;
cout << "\nElement was succesfully pushed\n";
}
}
//Read + Delete
T pop() {
if (top == -1)
cout << "\nStack is empty\n";
else {
T temp = stackPr[top];
stackPr[top] = 0;
top--;
cout << "\nElement was succesfully poped and deleted\n";
return temp;
}
}
//Read
T popup() {
if (top == -1)
cout << "\nStack is empty\n";
else {
cout << "\nElement was succesfully popped\n";
return stackPr[top];
}
}
//Comparison of 2 stacks
bool comparison(T &stack) {
if (size == stack.size)
for (int i = 0; i < size; i++) {
if (!this->stackPr[i].comparison(stack.stackPr[i]))
return false;
}
else
return false;
return true;
}
};
Try this, in your Stack class
change:
bool comparison(T &stack) {
for this:
bool comparison(Stack<T> &stack) {
First of all, abandon this comparison function, it hinders your code, use == instead.
Secondly, use const Stack<T> in your comparison function.
And finally, use auto to deduce the type of the variables.
Here is an example that shows the basics of what I just wrote:
#include <iostream>
using namespace std;
struct Time
{
bool operator==(const Time& time)
{
return true;// adjust it with your own needs.
}
};
template<typename T>
struct Stack
{
T val;
Stack(T& val_): val(val_) {}
bool operator==(const Stack<T>& stack)
{
return this->val == stack.val; // here is your business logic of comparison
}
};
int main()
{
Time t1;
Time t2;
Stack<Time> myStack1(t1);
Stack<Time> myStack2(t2);
auto temp = myStack1 == myStack2;
cout << temp << endl;
return 0;
}
I'm trying to work with this heap. I'm inserting a few random numbers then removing them to make sure my heap works. The problem is when I'm removing them I get duplicate numbers that shouldn't exist in the Heap. Pretty much I'll insert the following numbers and get back in return: 5 2 10 10 for some reason.
My main looks like this:
#include <iostream>
#include <fstream>
using namespace std;
#include "heap.h"
int main(void)
{
Heap<int> inlist(4);
inlist.insert(5);
inlist.insert(2);
inlist.insert(3);
inlist.insert(10);
int test;
while(inlist.remove(test))
cout << test << endl;
}
And my Heap looks like this:
#ifndef HEAP_H
#define HEAP_H
template<typename TYPE>
class Heap
{
private:
TYPE* heapData;
int currSize;
int capacity;
void _siftUp(int);
void _siftDown(int);
int _leftChildOf(int) const;
int _parentOf(int) const;
public:
Heap(int c = 100);
~Heap();
bool viewMax(TYPE&) const;
int getCapacity() const;
int getCurrSize() const;
bool insert(const TYPE&);
bool remove(TYPE&);
};
template<typename TYPE>
Heap<TYPE>::Heap(int c = 100)
{
capacity = 100;
currSize = 0;
heapData = new TYPE[capacity];
}
template<typename TYPE>
Heap<TYPE>::~Heap()
{
delete[] heapData;
currSize = 0;
capacity = 0;
}
template<typename TYPE>
bool Heap<TYPE>::insert(const TYPE& dataIn)
{
bool success = false;
if(currSize < capacity)
{
heapData[currSize] = dataIn;
_siftUp(currSize);
currSize++;
success = true;
}
return success;
}
template<typename TYPE>
void Heap<TYPE>::_siftUp(int child)
{
TYPE temp;
int parent;
if(child > 0)
{
parent = _parentOf(child);
if(heapData[child] > heapData[parent])
{
temp = heapData[parent];
heapData[parent] = heapData[child];
heapData[child] = temp;
_siftUp(child);
}
}
}
template<typename TYPE>
bool Heap<TYPE>::remove(TYPE& dataOut)
{
bool success = false;
if(currSize > 0)
{
dataOut = heapData[0];
currSize--;
heapData[0] = heapData[currSize];
_siftDown(0);
success = true;
}
return success;
}
template<typename TYPE>
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int child = _leftChildOf(parent);
if(child < currSize)
{
if((child + 1 < currSize) && (heapData[child] < heapData[child + 1]))
child++;
if(child)
{
temp = heapData[child];
heapData[child] = heapData[child + 1];
heapData[child + 1] = temp;
_siftDown(child);
}
}
}
template<typename TYPE>
int Heap<TYPE>::_leftChildOf(int p) const
{
return(2 * p + 1);
}
template<typename TYPE>
int Heap<TYPE>::_parentOf(int c) const
{
return((c - 1) / 2);
}
//**************************************************************************
template<typename TYPE>
int Heap<TYPE>::getCapacity() const
{
return capacity;
}
template<typename TYPE>
int Heap<TYPE>::getCurrSize() const
{
return currSize;
}
template<typename TYPE>
bool Heap<TYPE>::viewMax(TYPE& max) const
{
return false;
}
#endif
I'm pretty sure the problem isn't when I'm inserting into my Heap but when I'm removing it.
EDIT I changed my _siftDown a bit - now the numbers show up 5 10 3 2
if(child)
{
temp = heapData[child];
heapData[child] = heapData[parent];
heapData[parent] = temp;
_siftDown(child);
}
Your _siftDown is broken,
template<typename TYPE>
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int child = _leftChildOf(parent);
if(child < currSize)
{
if((child + 1 < currSize) && (heapData[child] < heapData[child + 1]))
child++;
if(child)
What's that meant to check? child is at this point either 2*parent + 1 or 2*parent + 2, without overflow, since parent should always be >= 0, that is always positive ~> condition fulfilled.
You need to check whether you want to swap heapData[parent] and heapData[child], so that condition should be if (heapData[parent] < heapData[child]).
{
temp = heapData[child];
heapData[child] = heapData[child + 1];
heapData[child + 1] = temp;
You are swapping the elements at index child and child+1, that's wrong. You should swap heapData[child] and heapData[parent] here.
_siftDown(child);
}
}
}
You also have an error in _siftUp,
template<typename TYPE>
void Heap<TYPE>::_siftUp(int child)
{
TYPE temp;
int parent;
if(child > 0)
{
parent = _parentOf(child);
if(heapData[child] > heapData[parent])
{
temp = heapData[parent];
heapData[parent] = heapData[child];
heapData[child] = temp;
_siftUp(child);
}
}
}
the recursive call should be _siftUp(parent), otherwise you never sift any item up more than one level.
Your remove method is good while your _siftDown has something wrong.
It's not always true that you siftdown with your left child.
void Heap<TYPE>::_siftDown(int parent)
{
TYPE temp;
int left= _leftChildOf(parent);
int right= _rightChildOf(parent);
int max= parent;
if(left< currSize && heapData[left] > heapData[max])
{
max= left;
}
if(right< currSize && heapData[right] > heapData[max])
{
max= right;
}
if( max!=parent ) //need to sift down
{
temp = heapData[max];
heapData[max] = heapData[parent];
heapData[parent] = temp;
_siftDown(max);
}
}
}
You can use the following functions instead of implementing your own heap:
std::make_heap
std::push_heap
std::pop_heap
You can find them in the algorithm header
heapData[0] = heapData[currSize];
Here you should not use heapData[currSize] otherwise you are copying the last elemnt of the heap to the top.
For example after removing 5 from the heap currSize is 3 and you do
heapData[0] = heapData[3];
which will create a duplicate of 10 at heapData[0].
Without taking a closer look on your code
You realize that test is never initialized?
int test; //initialization should happen here
while(inlist.remove(test))
cout << test << endl;
I also do not understand what the purpose of the parameter at Heap::remove(dataOut) is. Would it differ from Heap::remove(void) ?
I am trying to simulate Conway's game of life using an implementation file I created, I have made good progress but unfortunately I am getting an error which confuses me. I think the problem is ignorance on my part of how to properly code templated functions, anyways this is my implementation file:
#include <list>
#ifndef HashTable_h
#define HashTable_h
using namespace std;
#define HASHTABLE_CAPACITY 1009
template <class DataType>
class HashTable
{
public:
HashTable(); // constructor
bool insert(DataType &a); // insert function for inserting value of dataType into table
bool retrieve(DataType &a); // retrieve function for retrieving value from table
bool replace(DataType &a); // function for replacing the value from the table with the parameter
bool remove(DataType& a);//removed function written and checked
//int getSizeOf() const;
void clear(); // for clearing the table
int size() const;
private:
list<DataType> table[HASHTABLE_CAPACITY]; // static array
int count;
int currentIndex;
typename list<DataType>::const_iterator it;
};
// constructor
template <class DataType>
HashTable<DataType>::HashTable()
{
list<DataType> table[HASHTABLE_CAPACITY];
count = 0;
currentIndex = -1;
}
// retrieve function
template <class DataType>
bool HashTable<DataType>::retrieve(DataType &a)
{
// get wrapped index
int wrappedIndex = a.hashCode() % HASHTABLE_CAPACITY;
if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;
// if the array location isn't occupied, fail
if (wrappedIndex < 0 || wrappedIndex >= HASHTABLE_CAPACITY || table[wrappedIndex].empty()) return false;
// iterator for traversing table values
typename list<DataType>::const_iterator it;
// if the keys match then replace the data
// if a collision occurs then return false
it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), a);
if(it == table[wrappedIndex].end())
return false;
a = *it;
return true;
}
// overloaded operator function
// function for inserting values
template <class DataType>
bool HashTable<DataType>::insert(DataType &value)
{
// get wrapped index
int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;
// iterator for traversing values in table
typename list<DataType>::iterator it;
// if array location is not "occupied", copy into array
// else if keys match, replace the data
if (table[wrappedIndex].empty())
{
table[wrappedIndex].push_back(value);
count++;
return true;
}
else
{
it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value);
if (it != table[wrappedIndex].end()) *it = value;
else {table[wrappedIndex].push_back(value); count++;}
}
return true;
}
// function for replacing values
template <class DataType>
bool HashTable<DataType>::replace(DataType &value)
{
// get wrapped index
int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;
if(table[wrappedIndex].empty()) return false;
// iterator for traversing the values in table
typename list<DataType>::const_iterator it;
it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value);
if(it == table[wrappedIndex].end()) return false;
value = *it;
table[wrappedIndex].erase(it);
count--;
return true;
}
template <class DataType>
bool HashTable<DataType>::remove(DataType &value)
{
// get wrapped index
int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;
if(table[wrappedIndex].empty()) return false;
// iterator for traversing the values in table
typename list<DataType>::iterator it;
// if array location is not "occupied", copy into array
// else if keys match, remove the data
it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value);
if(it == table[wrappedIndex].end()) return false;
value = *it;
table[wrappedIndex].erase(it);
count--;
return true;
}
// function for clearing the table of it's values
template <class DataType>
void HashTable<DataType>::clear()
{
count = 0;
currentIndex = -1;
for(int i = 0; i < HASHTABLE_CAPACITY; i++)
if( !table[i].empty()) table[i].clear();
}
template <class DataType>
int HashTable<DataType>::size() const
{
return count;
}
#endif
And this is the actual Game Of Life driver file:
// Lab 11b
#include <iostream>
using namespace std;
struct cell
{
int value; // equal to 1, so 0,0 is not a blank
int row; // any +/0/- value
int col; // any +/0/- value
bool operator==(const cell& c) const {return row == c.row && col == c.col;}
bool operator<(const cell& c) const {return (1000000 * row + col) < (1000000 * c.row + c.col);}
int hashCode() const {return 31 * row + col;}
};
#include "HashTable.h"
HashTable<cell> grid;
HashTable<cell> newGrid;
const int MINROW = -25;
const int MAXROW = 25;
const int MINCOL = -35;
const int MAXCOL = 35;
int neighborCount(int row, int col)
{
cell temp;
int count = 0;
for (temp.row = row - 1; temp.row <= row + 1; temp.row++)
for (temp.col = col - 1; temp.col <= col + 1; temp.col++)
if (temp.row != row || temp.col != col)
if (grid.retrieve(temp))
++count;
return count;
}
void initialize()
{
cout << "List the coordinates for living cells.\n";
cout << "Terminate the list with a special pair -1 -1\n";
cell temp;
while (true)
{
cin >> temp.row >> temp.col;
if (temp.row == -1 && temp.col == -1) break;
grid.insert(temp);
}
cin.ignore();
}
void print()
{
cell temp = {1};
cout << "\nThe current Life configuration is:\n";
for (temp.row = MINROW; temp.row <= MAXROW; temp.row++)
{
for (temp.col = MINCOL; temp.col <= MAXCOL; temp.col++)
if (grid.retrieve(temp))
cout << '*';
else
cout << ' ';
cout << endl;
}
cout << endl;
}
void update()
{
cell temp = {1};
newGrid.clear();
for (temp.row = MINROW; temp.row <= MAXROW; temp.row++)
for (temp.col = MINCOL; temp.col <= MAXCOL; temp.col++)
switch (neighborCount(temp.row, temp.col))
{
case 2:
if (grid.retrieve(temp)) newGrid.insert(temp);
break;
case 3:
newGrid.insert(temp);
break;
}
grid = newGrid;
};
int main()
{
cout << "Welcome to Conway's game of Life\n";
cout << "This game uses a grid in which\n";
cout << "each cell can either be occupied by an organism or not.\n";
cout << "The occupied cells change from generation to generation\n";
cout << "according to the number of neighboring cells which are alive.\n";
initialize();
print();
for (int i = 1; grid.size(); i++)
{
cout << "Generation " << i << ". Press ENTER to continue, X-ENTER to quit...\n";
if (cin.get() > 31) break;
update();
print();
}
return 0;
}
When I try to compile these files I get this error:
In file included from GameOfLife.cpp:16:
HashTable.h: In member function ‘bool HashTable<DataType>::retrieve(DataType&) [with DataType = cell]’:
GameOfLife.cpp:32: instantiated from here
HashTable.h:74: error: no matching function for call to ‘find(std::_List_iterator<cell>, std::_List_iterator<cell>, cell&)’
HashTable.h: In member function ‘bool HashTable<DataType>::insert(DataType&) [with DataType = cell]’:
GameOfLife.cpp:47: instantiated from here
HashTable.h:117: error: no matching function for call to ‘find(std::_List_iterator<cell>, std::_List_iterator<cell>, cell&)’
What could be the issue here?
You need to #include <algorithm> to get std::find. This is presumably what you want to use when you call find. You should avoid using namespace std, specially in headers.
I've got this merge sort function
namespace sorted{
template<typename T>
class list {
/* other stuff */
list<T>* slice(int from, int to){
from = (from < 0) ? 0 : from;
to = (to > this->len) ? this->len : to;
list<T>* result = new list<T>();
node<T> *n = this->head;
int idx = 0;
while (n && (idx < this->len)){
if ((from <= idx) && (idx <= to)) result->append(n->value);
if (idx > to) break;
n = n->next;
idx++;
}
return result;
}
}
template<typename T>
list<T>* merge(list<T>* left, list<T>* right){
list<T>* result = new list<T>();
while ((left->length() > 0) || (right->length() > 0)){
if ((left->length() > 0) && (right->length() > 0)){
T l = left->get(0);
T r = right->get(0);
if (l <= r){
result->append(l);
left->remove(0);
} else{
result->append(r);
right->remove(0);
}
continue;
}
if (left->length() > 0) {
result->append(left->get(0));
left->remove(0);
}
if (right->length() > 0) {
result->append(right->get(0));
right->remove(0);
}
}
return result;
}
template<typename T>
list<T>* merge_sort(list<T>* original){
if (original->length() <= 1) {
return original;
}
int len = original->length();
list<T>* left = NULL;
list<T>* right = NULL;
if (len > 2){
left = original->slice(0,(len/2));
right = original->slice((len/2)+1,len-1);
}else if (len == 2){
left = original->slice(0,0);
right = original->slice(1,1);
}
left = merge_sort(left);
right = merge_sort(right);
delete original;
list<T>* result = merge(left, right);
delete left;
delete right;
return result;
}
/* other stuff */
}
And here's my main method
int main(int argc, char** argv){
sorted::list<int>* l = get_random_list();
l = merge_sort(l);
for (int i = 0; i < (l->length() - 1); i++){
int t = l->get(i);
int u = l->get(i+1);
if (t > u){
sorted::list<int>* m = l->slice(i - 5, i + 5);
cout << m << endl;
delete m;
break;
}
}
delete l;
return 0;
}
Link to bitbucket.org project
My question was this.
If the list is returned properly from the slicing function, why would it not be returned to the main function properly, if its being done the same way?
[Update] Added functions as they're currently functioning the way they should be. A full version is up on bitbucket.
After checking your full code in the link you provided, I can definitely say the problem is because you don't have an assignment operator.
What happens now is that the assignments of the lists will use the default assignment operator that is automatically generated by the compiler. This does a shallow copy, so the list on the left hand side of the assignment will have its pointers be the same as for the list on the right hand side. This means that when the local variable you return goes out of scope, it will of course invoke the destructor which deletes the lists. Now the copy have pointers which points to deleted memory, and accessing thos pointers is undefined behavior. This is why it seems to work in one place and not the other.