I have created my vector class template and I have already done my employee classes of hourly and I salaried. I want to use the vector of employee pointers instead of the array of employee pointers, I'm trying to do that but when I run it just breaks while I have no error listed.
Also, I have used the at function like( payroll.at(i)->writeFile(out); ) to get access to an element, but I don't know what's wrong.
Any suggestion?
Thanks
here is my code:
myvector class template:
#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>
const int CAPACITY = 4;
template <class T>
class MyVector {
public:
MyVector();
MyVector( int size);
MyVector( int size, const T & initial);
MyVector(const MyVector<T> & v);
~MyVector();
int capacity() const;
int size() const;
void push_back(const T & value);
//T & operator[](unsigned int index);
MyVector<T> & operator=(const MyVector<T> &);
void clear();
T at(int i);
friend ostream& operator<<(ostream &out, const MyVector<T>& );
private:
int applied;
int my_size;
int my_capacity;
T * buffer;
T * daArray;
};
template<class T>
MyVector<T>::MyVector()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
applied = 0;
}
template<class T>
MyVector<T>::MyVector(const MyVector<T> & v)
{
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T[my_size];
for ( int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
}
template<class T>
MyVector<T>::MyVector(int size)
{
my_capacity = size;
my_size = size;
buffer = new T[size];
}
template<class T>
MyVector<T>::MyVector( int size, const T & initial)
{
my_size = size;
my_capacity = size;
buffer = new T [size];
for (unsigned int i = 0; i < size; i++)
buffer[i] = initial;
//T();
}
template<class T>
MyVector<T> & MyVector<T>::operator = (const MyVector<T> & v)
{
delete[ ] buffer;
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T [my_size];
for (int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
return *this;
}
template<class T>
void MyVector<T>::push_back(const T & i)
{
if (my_capacity == 0)
{
my_capacity = 1;
my_size = 1;
applied= 0;
buffer = new T[1];
buffer[0] = i;
}
else
{
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
my_size++;
applied++;
buffer[applied] = i;
}
else
{
if (my_size == applied + 1)
my_size++;
applied++;
buffer[applied] = i;
}
}
}
template<class T>
int MyVector<T>::size()const//
{
return my_size;
}
template<class T>
int MyVector<T>::capacity()const
{
return my_capacity;
}
template<class T>
MyVector<T>::~MyVector()
{
delete[ ] buffer;
}
template <class T>
void MyVector<T>::clear()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
}
template <class T>
T MyVector<T>::at(int i)
{
if (i < 0 || i > my_size -1)
{
string error = "Index is undefined";
throw error;
}
return buffer[i];
}
template <class T>
ostream& operator<<(ostream &out, const MyVector<T>& v)
{
for (unsigned i = 0; i < v.size(); i++)
{
out << v[i] << " ";
}
return out;
}
main
int main() {
MyVector< employee*> payroll;
payroll.push_back(new Hourly ("H. Potter", "Privet Drive", "201-9090", 40, 12.00));
payroll.push_back(new Salaried ( "A. Dumbledore", "Hogewarts", "803-1230", 1200));
ofstream out;
out.open(file);
if (out.fail()) {
cout<<" could not open the file"<<endl;
system("PAUSE");
}
for (int i = 0; i < SIZE; i++) {
payroll.at(i)->writeFile(out);
}
out.close( );
}
You have a bug in your push_back method. You need something like this
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
buffer = daArray; // new line here
my_size++;
applied++;
buffer[applied] = i;
}
See where I've put the comment // new line here
Related
I am trying to merge two dynamic arrays but I am getting an error in my merge function that
"data': is not a member of 'List<T>"
I know that the error is ocuring because the given parameter in the merge(const List& other) is list but I am confused how to access my ArrayList2 which has been passed in merge function in the main
my code is:
#include <iostream>
using namespace std;
template<class T>
class List {
public:
// return the capacity of the list
virtual size_t capacity() const = 0;
// return the number of elements in the list
virtual size_t size() const = 0;
// inserts an element to the beginning
virtual void push_front(const T& value) = 0;
// adds an element to the end
virtual void push_back(const T& value) = 0;
// removes the last element
virtual void pop_back() = 0;
// removes the first element
virtual void pop_front() = 0;
// remove the first occurrence of an element with the given value
virtual void remove(const T& val) = 0;
// merges two sorted lists
virtual void merge(const List<T>& other) = 0;
virtual ~List() {}
};
template<class T>
class ArrayList : public List<T>
{
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
ArrayList() = delete; // disable default constructor
// constructor
ArrayList(size_t capacity) : max_capacity(capacity), num_of_element(0) {
data = new T[capacity];
}
// copy constructor
ArrayList(const ArrayList<T>& other_list) : max_capacity(other_list.max_capacity),
num_of_element(other_list.num_of_element) {
data = new T[max_capacity];
for (size_t i = 0; i < other_list.num_of_element; i++) {
data[i] = other_list.data[i];
}
}
// destructor
virtual ~ArrayList() {
delete[]data;
}
size_t capacity() const override {
return max_capacity;
}
size_t size() const override {
return num_of_element;
}
T& operator[](int index) {
return data[index];
}
bool operator==(const ArrayList<T>& other_list) {
// not comparing capacity as eventually array list can be made capacity irrelevant using dynamic allocation
if (num_of_element != other_list.num_of_element) {
return false;
}
for (int i = 0; i < num_of_element; i++) {
if (data[i] != other_list.data[i]) {
return false;
}
}
return true;
}
void push_front(const T& value)
{
}
void push_back(const T& value)
{
if (max_capacity > num_of_element)
{
num_of_element++;
data[num_of_element - 1] = value;
}
}
void pop_back()
{
}
void pop_front()
{
}
void remove(const T& val)
{
int i = 0, j;
while (i < max_capacity)
{
if (data[i] == val)
{
for (int j = i; j < num_of_element-1; j++)
data[j] = data[j + 1];
if (data[i] == val && (i + 1) > num_of_element - 1)
{
data[i] = {};
num_of_element--;
break;
}
num_of_element--;
}
else
i++;
}
}
void merge(const List<T>& other)
{
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++)
temp[i] = data[i];
for (int j = 0; j < other.size(); j++)
{
temp[i] = other.data[j]; //I am getting error on this line
i++;
}
}
private:
void shift_left_to(size_t start) {
for (size_t i = start; i < num_of_element - 1; i++) {
data[i] = data[i + 1];
}
}
};
int main() {
ArrayList<int> list1(3);
list1.push_back(3);
list1.push_back(1);
list1.push_back(1);
ArrayList<int> list2(2);
list2.push_back(1);
list2.push_back(8);
list1.merge(list2);
/* for (size_t i = 0; i < list1.size(); i++)
cout<<list1[i]<<" ";
cout<<"Size:"<<list1.size()<<" Capacity:"<<list1.capacity();*/
system("pause");
return 0;
}
Presumably, all of your concrete List<T> classes (e.g. ArrayList<T>) will have some kind of accessors to the elements. You can make those accessors part of the List<T> interface and call them in the implementation of void merge(List<T> const&). As an example:
template <class T>
class List {
public:
// ...
virtual T& operator[](int index) = 0;
virtual T const& operator[](int index) const = 0;
};
template <class T>
class ArrayList : public List<T> {
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
// ...
T& operator[](int index) override { return data[index]; }
T const& operator[](int index) const override { return data[index]; }
// ...
void merge(const List<T>& other) {
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++) temp[i] = data[i];
for (int j = 0; j < other.size(); j++) {
temp[i] = other[j]; // < Use your List<T>::operator[] here
i++;
}
}
// ...
};
I'd say the message is quite descriptive: List does not have a member called data. You should use the [] operator instead to access the list elements in the merge function. [] operator is implemented by descendants of List.
temp[i] = other[j]
I've got two classes (structs) - Editor and Matrix. The matrix itself is working fine. But if I want to use Matrix via Editor, it's not working. I believe there is some problem with memory because I can't deallocate and even use matrix inside the Editor struct. I've tried to allocate the matrix dynamically, but then I couldn't use the addRow method.
Not really good with c++, but have to use those classes, can't use std::vector and stuff like that.
Editor definition:
struct Editor
{
private:
Matrix<std::string> data;
public:
Editor();
Editor(Matrix<std::string> oldData);
~Editor();
void addRow(std::string* row);
int getNumberOfRows();
int getNumberOfColumns();
};
Editor implementation:
using namespace std;
Editor::Editor()
{
}
Editor::Editor(Matrix<string> oldData)
{
data = oldData;
}
Editor::~Editor()
{
}
void Editor::addRow(std::string* row)
{
data.addRow(row);
}
int Editor::getNumberOfRows()
{
return this->data.getNumberOfRows();
}
int Editor::getNumberOfColumns()
{
return this->data.getNumberOfColumns();
}
Matrix definition:
template<typename T>
struct Matrix
{
private:
T** data;
int numberOfRows;
int numberOfColumns;
public:
Matrix(int numberOfRows, int numberOfColumns);
Matrix(const Matrix<T>& m);
~Matrix();
int getNumberOfRows();
int getNumberOfColumns();
T getItem(int indexRow, int indexColumn) const;
void addRow(T* newRow);
T** getData();
};
Matrix implementation:
template<typename T>
inline Matrix<T>::Matrix(int numberOfRows, int numberOfColumns)
{
this->numberOfColumns = numberOfColumns;
this->numberOfRows = numberOfRows;
this->data = new T * [numberOfRows];
for (int i = 0; i < this->numberOfRows; i++)
{
this->data[i] = new T[numberOfColumns];
}
}
template<typename T>
inline Matrix<T>::Matrix(const Matrix<T>& m)
{
numberOfRows = m.numberOfRows;
numberOfColumns = m.numberOfColumns;
if (m.data)
{
data = new T * [numberOfRows];
for (int i = 0; i < numberOfRows; i++)
data[i] = new T[numberOfColumns];
for (int i = 0; i < numberOfRows; i++)
{
for (int j = 0; j < numberOfColumns; j++)
{
data[i][j] = m.data[i][j];
}
}
}
}
template<typename T>
inline Matrix<T>::~Matrix()
{
for (int i = 0; i < this->numberOfRows; i++)
{
delete[] data[i];
}
delete[] data;
}
template<typename T>
inline int Matrix<T>::getNumberOfRows()
{
return this->numberOfRows;
}
template<typename T>
inline int Matrix<T>::getNumberOfColumns()
{
return this->numberOfColumns;
}
template<typename T>
inline T** Matrix<T>::getData()
{
return this->data;
}
template<typename T>
inline T Matrix<T>::getItem(int indexRow, int indexColumn) const
{
if (indexRow < 0 || indexRow > numberOfRows || indexColumn < 0 || indexColumn > numberOfColumns)
{
throw std::exception("not valid at least one of those indexes");
}
return this->data[indexRow][indexColumn];
}
template<typename T>
inline void Matrix<T>::addRow(T* newRow)
{
if (newRow == nullptr)
{
throw std::exception("not valid row");
}
T** newData = new T * [numberOfRows + 1];
for (int i = 0; i < numberOfRows + 1; i++)
{
newData[i] = new T[numberOfColumns];
for (int j = 0; j < numberOfColumns; j++)
{
if (i != this->numberOfRows)
{
newData[i][j] = data[i][j];
}
else {
newData[i][j] = newRow[j];
}
}
}
for (int i = 0; i < this->numberOfRows; i++)
{
delete[] this->data[i];
}
delete[] this->data;
this->data = newData;
this->numberOfRows++;
}
Main:
using namespace std;
int main()
{
Matrix<string> mt{1,1};
string* st = new string[3];
st[0] = "aa";
st[1] = "bb";
st[2] = "cc";
mt.addRow(st); // works
Editor ed{ mt };
ed.addRow(st); // doesn't work
return 0;
}
It crashes in xstring* on this:
_CONSTEXPR20_CONTAINER void _Copy_assign(const basic_string& _Right, false_type) {
_Pocca(_Getal(), _Right._Getal());
assign(_Right._Mypair._Myval2._Myptr(), _Right._Mypair._Myval2._Mysize);
}
with code:
Exception: Read access violation.
_Right – 0xDDDDDDDD.
EDIT:
Did cut most of the stuff from the project to just show the minimum. Anyway, the answer with semi-shallow copy was the right. Altho I thought
struct = struct;
calls for copy constructor. But it seems that it doesn't. I had to add operator= to somehow make it work properly.
I have a class that takes the in an array and its size. in the class I have an index operator "[]" that has been overloaded to pass in its contents to a class member function and return that function. It also checks if I am accessing contents out side of the array size.
this_type operator[] (int index)
{
assert (index > 0 && index<=len);
at(index);
return c_arr()[index];
}
I made a copy constructor for it
//constructor
my_array(this_type const arr[], int size)
{
len = size;
assert(arr != NULL);
assert(size >= 0);
this->arr = new this_type[size];
for (int i = 0; i < size; i++)
(*this).arr[i] = arr[i];
}
//copy constructor
my_array( const my_array<this_type> & arr)
{
this->arr = new this_type[sizeof(arr)];
memcpy(this->arr, arr.arr, sizeof(this_type)*arr.len);
}
my_array(int size)
{
len = size;
assert(size >= 0);
this->arr = new this_type[size];
}
But it does not seem to pass in the array size value when called to the member function "len". Any thoughts?
#include <iostream>
#include <cassert>
#include <assert.h>
using namespace std;
template <class this_type>
class my_array
{
private:
this_type *arr;
int len;
int sum()
{
int sum;
for (int i = 0; i < len; i++)
sum += arr[i];
}
public:
int size() const
{
return len;
}
this_type &at(int index)
{
assert( index >= 0 && index < len);
return arr[index];
}
my_array(this_type const arr[], int size)
{
len = size;
assert(arr != NULL);
assert(size >= 0);
this->arr = new this_type[size];
for (int i = 0; i < size; i++)
(*this).arr[i] = arr[i];
}
my_array( const my_array<this_type> & arr)
{
this->arr = new this_type[sizeof(arr)];
memcpy(this->arr, arr.arr, sizeof(this_type)*arr.len);
}
my_array(int size)
{
len = size;
assert(size >= 0);
this->arr = new this_type[size];
}
~my_array()
{
delete[] arr;
}
this_type* c_arr()
{
return arr;
}
this_type & operator[] (int index)
{
assert (index > 0 && index<=len);
at(index);
return c_arr()[index];
}
this_type operator[] (int index)
{
assert (index > 0 && index<=len);
at(index);
return c_arr()[index];
}
friend istream & operator>>(istream &lhs, my_array<this_type> &rhs);
friend ostream & operator<<(ostream &lhs, my_array<this_type> &rhs);
};
template <class this_type>
ostream & operator<<(ostream &lhs, my_array<this_type>&rhs)
{
for ( int i = 0; i < rhs.size(); i++)
lhs << rhs.arr[i] << endl;
return lhs;
}
template <class this_type>
istream & operator>>(istream &lhs, my_array<this_type> &rhs)
{
for ( int i = 0; i < rhs.size(); i++)
lhs >> rhs.arr[i];
return lhs;
}
int main()
{
char arra[5]={'c','o','d','e','s'};
my_array<char> arr(arra,5), arr1(5), arr2(arr);
for(int t=0;t< 9;t++)
{
//use the operator that is attached to the class instance
cout << arr2[t];
}
for(int t=0;t< 9;t++)
{
cout<<arr2.c_arr()[t];
}
return 0;
}
this->arr = new this_type[sizeof(arr)];
This line from your copy constructor is not correct. arr is an object of your my_array class. sizeof(arr) is a compile time constant, and completely independent of the number of elements allocated for the array. Those elements are not even contained in the class. They are on the free store, and the class holds a pointer to them. What you want instead is this:
this->arr = new this_type[arr.len];
You also want to assign to the len member of the object you are constructing.
this->len = arr.len;
I am obliged to say that, unless you are creating this class for learning purposes, just use std::vector.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 9 years ago.
I am writing a simple data structure library, while I met some problems.
I wrote three files. collections.h is the header file, collections.cpp is to implement the methods declared in header file, main.cpp is for test. But compile error occurs:
Undefined reference to List::GetCount() const;
Undefined reference to List::IsEmpty() const;
Undefined reference to List::Add(int);
...// And so on.
I provide my code below, where is the problem?
collections.h:
#ifndef COLLECTIONS_H
#define COLLECTIONS_H
#include <windows.h>
#include <stdexcept>
template<typename T>
class ISequenceList
{
protected:
ISequenceList() { }
public:
virtual int GetCount() const = 0;
virtual bool IsEmpty() const = 0;
virtual void Add(T item) = 0;
virtual void AddRange(const T *items, int length) = 0;
virtual T &ElementAt(int index);
virtual bool InsertAt(T item, int index);
virtual bool Remove(T item) = 0;
virtual bool RemoveAt(int index) = 0;
virtual bool Contains(T item) = 0;
};
template<typename T>
class List : public ISequenceList<T>
{
private:
int _count;
int _capacity;
T *_array;
void ExpandCapacity();
public:
List(int capacity = 100)
{
if (capacity <= 0)
std::__throw_invalid_argument("The capcity can't be 0 or below.");
this->_count = 0;
this->_capacity = capacity;
this->_array = (T*)malloc(_capacity* sizeof(T));
}
List(const List &other)
{
if (this == other)
return;
this->_count = other->_count;
this->_capacity = other->_capacity;
free(_array);
this->_array = other->_array;
}
List &operator=(const List &other)
{
this = other;
}
~List()
{
if (_array)
free(_array);
}
int GetCount() const;
bool IsEmpty() const;
T &ElementAt(int index);
void Add(T item);
void AddRange(const T *items, int length);
bool InsertAt(T item, int index);
bool Remove(T item);
bool RemoveAt(int index);
bool Contains(T item);
};
#endif
collections.cpp:
#include "collections.h"
template<typename T>
void List<T>::ExpandCapacity()
{
T *temp = this->_array;
this->_array = (T*)malloc((this->_capacity << 1) * sizeof(T));
memcpy(this->_array, temp, this->_capacity * sizeof(T));
this->_capacity = this->_capacity << 1;
free(temp);
}
template<typename T>
int List<T>::GetCount() const
{
return this->_count;
}
template<typename T>
bool List<T>::IsEmpty() const
{
return this->_count == 0;
}
template<typename T>
void List<T>::Add(T item)
{
this->_array[_count] = item;
_count++;
if (_count == _capacity)
this->ExpandCapacity();
}
template<typename T>
void List<T>::AddRange(const T *items, int length)
{
if (length <= 0)
std::__throw_invalid_argument("The length can't be 0 or below.");
if (!items)
std::__throw_invalid_argument("The items can't be null");
int totalLength = this->_count + length;
if (totalLength >= this->_capacity)
{
T *temp = this->_array;
this->_array = (T*)malloc((totalLength << 1) * sizeof(T));
memcpy(_array, temp, this->_capacity);
free(temp);
}
this->_array += this->_capacity;
memcpy(_array, items, length * sizeof(T));
this->_capacity = totalLength << 1;
this->_count += length;
}
template<typename T>
T &List<T>::ElementAt(int index)
{
if (index < 0 || index >= _count )
std::__throw_invalid_argument("The index is out of bound.");
return _array[index];
}
template<typename T>
bool List<T>::InsertAt(T item, int index)
{
if (index < 0 || index > _count)
return false;
if (index == _count)
{
this->Add(item);
return true;
}
for (int i = _count; i > index; i--)
{
_array[i] = _array[i - 1];
}
_array[index] = item;
_count++;
if (_count == _capacity)
this->ExpandCapacity();
return true;
}
template<typename T>
bool List<T>::Remove(T item)
{
for (int i = 0; i < _count; i++)
{
if (_array[i] == item)
{
for (int j = i; j < _count; j++)
{
_array[j] = _array[j + 1];
}
_count--;
return true;
}
}
return false;
}
template<typename T>
bool List<T>::RemoveAt(int index)
{
if (index < 0 || index >= _count)
return false;
for (int j = index; j < _count; j++)
{
_array[j] = _array[j + 1];
}
_count--;
return true;
}
template<typename T>
bool List<T>::Contains(T item)
{
for (int i = 0; i < _count; i++)
{
if (_array[i] == item)
return true;
}
return false;
}
main.cpp:
#include "collections.h"
#include <iostream>
int main()
{
List<int> *seqList = new List<int>();
seqList->Add(5);
int arr[100] = {0};
seqList->AddRange(arr, 50);
seqList->ElementAt(5) = 111;
seqList->InsertAt(100, 15);
seqList->Remove(50);
seqList->ElementAt(44) = 44;
seqList->RemoveAt(44);
if (seqList->Contains(111))
std::cout << "Yes" << std::endl;
for (int i = 0; i < seqList->GetCount(); i++)
{
std::cout << seqList->ElementAt(i) << "\t";
}
return 0;
}
I have defined all the methods in List, but why can't the complier recognize? Where is the problem? Thanks for anyone who help me..
Note: my ide is Code::Blocks
Implementation of the template functions must be in a header; it can't be in a separate source file. The compiler needs to see it at the point where the template is used and its arguments become known.
I have problem in implementing a disjoint set ADT in C++ due to the fact that our teacher only explained the union and find operations. I fully understand the concepts of union and find but I am still confused about how to implement them.
Could someone please give me an idea of the implementation and also explain what the interface of this data structure should look like?
You have way too many requirements, we're not here to do your homework for you.
Have a look at http://en.wikipedia.org/wiki/Disjoint-set_data_structure
#include <iostream>
template<typename T>
class Disjoint_sets
{
public:
int FIND(int pos);
bool in_same_set(T data_element_1, T data_element_2);
void UNION_IF_EQUIVALENT(T data_element_1, T data_element_2);
void UNION(T data_element_1, T data_element_2);
Disjoint_sets(bool (*is_equivalent)(T, T));
Disjoint_sets();
Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T),int size);
void insert(T data_element);
bool is_root(int pos_number);
int get_pos(T data_element);
void partition();
void print_partition();
private:
T* data;
int* parent_pos;
int* number_of_children;
int size;
bool (*isequivalent)(T D1, T D2);
};
template<typename T>
Disjoint_sets<T>::Disjoint_sets()
{
data = NULL;
parent_pos = NULL;
number_of_children = NULL;
size = 0;
isequivalent = NULL;
}
template<typename T>
Disjoint_sets<T>::Disjoint_sets(bool (*is_equivalent)(T, T))
{
isequivalent = is_equivalent;
data = NULL;
parent_pos = NULL;
number_of_children = NULL;
size = 0;
}
template<typename T>
Disjoint_sets<T>::Disjoint_sets(T* data_arr, bool (*is_equivalent)(T, T), int size)
{
data = new T[size];
parent_pos = new int[size];
number_of_children = new int[size];
this->size = size;
isequivalent = is_equivalent;
for (int i = 0; i < size; i++)
{
data[i] = data_arr[i];
parent_pos[i] = -1;
number_of_children[i] = 0;
}
}
template<typename T>
bool Disjoint_sets<T>::is_root(int pos)
{
if (pos<0 && pos>size - 1)
{
std::cout << "Error, invalid pos supplied to is_root\n";
return false;
}
if (parent_pos[pos] == -1)
{
return true;
}
else
{
return false;
}
}
template <typename T>
int Disjoint_sets<T>::FIND(int pos)
{
while (!is_root(pos))
{
pos = parent_pos[pos];
}
return pos;
}
template<typename T>
bool Disjoint_sets<T>::in_same_set(T data_element_1, T data_element_2)
{
return FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2));
}
template<typename T>
int Disjoint_sets<T>::get_pos(T data_element)
{
for (int i = 0; i < size; i++)
{
if (data[i] == data_element)
{
return i;
}
}
std::cout << "Could not find element\n";
return -1;
}
template <typename T>
void Disjoint_sets<T>::UNION(T data_element_1, T data_element_2)
{
int data_parent_1_pos = FIND(get_pos(data_element_1));
int data_parent_2_pos = FIND(get_pos(data_element_2));
if ( data_parent_1_pos==data_parent_2_pos )
{
return;
}
if (number_of_children[data_parent_1_pos] >= number_of_children[data_parent_2_pos])
{
parent_pos[data_parent_2_pos] = data_parent_1_pos;
}
else
{
parent_pos[data_parent_1_pos] = data_parent_2_pos;
}
}
template <typename T>
void Disjoint_sets<T>::UNION_IF_EQUIVALENT(T data_element_1, T data_element_2)
{
if (FIND(get_pos(data_element_1)) == FIND(get_pos(data_element_2)))
{
return;
}
if (isequivalent(data_element_1, data_element_2))
{
UNION(data_element_1, data_element_2);
}
}
template<typename T>
void Disjoint_sets<T>::partition()
{
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
UNION_IF_EQUIVALENT(data[i], data[j]);
}
}
}
template <typename T>
void Disjoint_sets<T>::print_partition()
{
for (int i = 0; i < size; i++)
{
if (is_root(i))
{
for (int j = 0; j < size; j++)
{
if (FIND(j) == i)
{
std::cout << data[j] << " ";
}
}
}
std::cout << "\n";
}
}
template <typename T>
bool lol(int a, int b)
{
return a * a == b * b;
}
int main()
{
int arr[6] = { -1,1,2,3,-3,4 };
Disjoint_sets<int> d(arr,lol<int>, 6);
d.partition();
d.print_partition();
}