I am getting garbage in erase function - c++

I am getting garbage in my user defined vector.Garbage comes after erase function this is the code
#if 1 // Make it 1 to enable this code
#include <iostream>
using namespace std;
class Vector{
protected:
int l;
int* v;
public:
Vector():l(0),v(0){
cout << "\nBase class: Vector: Default constructor" << endl;
}
Vector( int len ):l(len),v(new int[l]) {
cout << "Vector: Overloaded constructor" << endl;
}
void set( int i, int val)
{
if( l )
v[i] = val;
else{
cout << "Error: zero size vector\n exiting..." <<endl;
exit(5);
}
}
int get( int i)
{
if( l )
return v[i];
else{
cout << "Error: zero size vector\n exiting..." <<endl;
exit(5);
}
}
~Vector(){
cout << "Base dextructor" <<endl;
delete [] v;
}
};
class Vector1:public Vector{
private:
public:
Vector1():Vector(){
cout << "Derived class: Vector1:: Default constructor" << endl;
}
//my functions
int size()
{
return l;
}
int front()
{
return Vector::get(0);
}
int end()
{
return Vector::get(l-1);
}
void swap(int a,int b)
{
int temp=v[a];
v[a]=v[b];
v[b]=temp;
}
void find(int val)
{
bool flag=false;
for(int i=0;i<l;i++)
{
if(v[i]==val)
{
flag=true;
}
}
if(flag==true)
cout<<"\nValue ="<<val<<" =Exists in Vector";
else
cout<<"\nValue ="<<val<<" =doesnot Exists in Vector";
}
void erase(int val)
{
int *temp=new int[l-1];
int k=0;
for(int i=0;i<l;i++)
{
if(v[i]!=val)
{
temp[i]=v[i];
k++;
}
}
delete []v;
l=l-1;
v=new int[l];
for(int i=0;i<l;i++)
{
v[i]=temp[i];
}
}
int resize( int len )
{
if( l )
delete [] v;
l = len;
v = new int[l];
return (v!=0);
}
void set( int i, int val)
{
if( i>= 0 && i<l )
Vector::set( i, val );
else{
cout << "Error: index out of range\n exiting..." <<endl;
exit(3);
}
}
int get( int i)
{
if( i>= 0 && i<l )
return Vector::get(i);
else{
cout << "Error: index out of range\n exiting..." <<endl;
exit(3);
}
}
int & operator [](int i)
{
return v[i];
}
Vector1( int len ):Vector(len)
{
}
};
int main()
{
Vector vec;
Vector1 v1;
v1.resize( 4 );
v1.set( 2, 4);
v1.set( 1, 5);
v1.set( 0, 6);
int x = v1[2];
v1[3] = 77;
cout<<"\nSize of vector is=\n"<<v1.size();
//v1.set( 5, 4); // erroneous value
cout<<"\nFront of vector is=\n"<<v1.front();
cout<<"\nEnd of vector is=\n"<<v1.end();
//do swap between values
cout<<"\n";
v1.swap(1,3);
//now values are
cout<<"v1[1] is equals to= "<<v1[1];
cout<<"v1[3] is equals to= "<<v1[3];
v1.find(5);
v1.find(100);
cout<<"\nNow v1[0] is equals to= \n"<<v1[0];
v1.erase(6);
cout<<"\nNow v1[0] is equals to= \n"<<v1[0]<<" "<<v1[1];
cout<<"\n";
}
#endif
Output is this
v1[0] should be be 5

In your erase function, you are not actually erasing the given number, you just copy every number in the vector that is not equal to the given number to a new array. E.g., if your internal array in the vector contained the numbers 2, 4, 6 and 8, and you are erasing 6, you just copy 2, 4 and 8 into a new array into indices 0, 1 and 3, while keeping slot 2 in the new array as undefined. Then you make a third array that is one shorter than the new array, and copy everything except the last item into the third array, including the undefined slot 2, but not the last slot (which should have been kept).
I think that using temp[k] = v[i] would solve your problem in the erase function, but note that it still won't be a perfect solution because the item being deleted might occur multiple times in the vector, or it might not be there at all, so it is not always the case that the new length is one smaller than the old length.

In the erase function, you should have temp[k] = v[i] and not temp[i] = v[i].

Related

Exception thrown: write access violation

I am trying to implement a list structure, but when I wrote the insert() function which inserts an element in a specific position in the list, I get an error Exception thrown: write access violation.
pl was 0x34812B3A.
I tried alot to fix it but I really can't. I used try..throw..catch and still didn't get it, so what should I do.
This is my code:
List.h
#pragma once
#define MAXLIST 100
typedef struct List {
int size;
int entry[MAXLIST];
}list;
void createl(list*);
int ListEmpty(list*);
int ListFull(list*);
int sizel(list*);
void destroyl(list*);
void insert(int, int, list*);
void deletei(int* , int, list*);
void traversel(list*, void (*)(int));
void retrieve(int*, int, list*);
void replace(int, int, list*);
//int access(int , list*);
and this is the implementation (List.cpp)
#include <iostream>
#include "List.h"
using namespace std;
void createl(list* pl) {
pl->size = 0;
}
int isEmpty(list* pl) {
return !(pl->size);
}
int isFull(list* pl) {
return (pl->size == MAXLIST);
}
int sizel(list* pl) {
return pl->size;
}
void destroyl(list* pl) {
pl->size = 0;
}
void insert(int e, int p, list* pl) { //insert element e in the postion p in the list
for (int i = pl->size -1; i >= p; i--) {
pl->entry[i+1] = pl->entry[i];
}
pl->entry[p] = e;
pl->size++;
}
void deletei(int* pe, int p, list* pl) {
*pe = pl->entry[p];
for (int i = p + 1; i < pl->size; ++i) {
pl->entry[i-1] = pl->entry[i];
}
pl->size--;
}
void traversel(list* pl, void (*pf)(int e)) {
for (int i = 0; i < pl->size; ++i) {
(*pf)(pl->entry[i]);
}
}
void retrieve(int* pe, int p, list* pl) {
*pe = pl->entry[p];
}
void replace(int e, int p, list* pl) {
pl->entry[p] = e;
}
/*int access(int p, list* pl) {
return pl->entry[p];
}*/
I get the error here in function insert()
pl->entry[p] = e;
and this is a program to just check if my code works.
#include <iostream>
#include "List.h"
using namespace std;
void display(int e) {
cout << e << "\n";
}
int main() {
list l;
list* ptl = &l;
int t;
cout << "Put 5 elements:\n";
for (int i = 0; i < 5; ++i) {
cin >> t;
insert(t, sizel(ptl), ptl);
}
cout << "The list looks like a stack\n\n";
traversel(ptl, display);
cout << "The size of the list is: " << sizel(ptl) << endl;
insert(9, 2, ptl);
cout << "The size of the list is: " << sizel(ptl) << endl;
int temp;
deletei(&temp, 2, ptl);
cout << temp <<endl ;
traversel(ptl, display);
cout << "The size of the list is: " << sizel(&l) << endl;
int t2;
retrieve(&t2, 2, ptl);
cout << t2 << endl;
replace(4, 1, ptl);
traversel(ptl, display);
destroyl(ptl);
cout << "The size of the list is: " << sizel(ptl) << endl;
return 0;
}
Thank you for your time and helping me.
You used ptl, which points at l, without initializing l.
Add initialization like this:
int main() {
list l;
list* ptl = &l;
int t;
createl(ptl); // add initialization
cout << "Put 5 elements:\n";
for (int i = 0; i < 5; ++i) {
cin >> t;
insert(t, sizel(ptl), ptl);
}

Tried making a hash table, can't map all keys, also program crashes

I have to make a program with a hash table that maps single random characters into the table. The program kind of works but sometimes it crashes, also it doesn't map every element. Some of them just won't get inside the table and there are always spare spaces in the table. I don't know what to do to solve these 2 problems. I used 3 versions of open adressing and each of them causes the same 2 problems. Sorry for my bad English. Thank you in advance.
Edited. Of course, I forgot about dynamic allocation. But the problem isn't solved.
#include <time.h>
#include <string>
#include <cstdlib>
using namespace std;
int Liniowo(int i, int proby, int rozmiar) // (open adressing, Linear probing)
{
if(i+proby<rozmiar)
return i+proby;
else
{
return -1;
}
}
int Kwadratowo(int i, int proby, int rozmiar) // (open adressing, Quadratic probing)
{
if (i+proby*proby<rozmiar)
return i+proby*proby;
else
{
return -1;
}
}
int Podwojnie(int i, int proby, int rozmiar, char klucz) // (open adressing, Double hashing)
{
if (i*(klucz*(701%klucz)-klucz%13)<rozmiar&&i*(klucz*(701%klucz)-klucz%13)>0)
return i*(klucz*(701%klucz)-klucz%13);
else
{
return -1;
}
}
int modularnie(char c,int rozmiar) // modular
{
return c%rozmiar;
}
void dodaj(char *tab,int max, char c) // add an element
{
int i=modularnie(c, max);
if (tab[i]== '\0')
tab[i]=c;
else
{
int u=0;
int h;
while (tab[i]!= '\0'&&h!=-1)
{
u++;
// h=Kwadratowo(i, u, max);
h=Podwojnie(i,u,max,c);
}
if (h!=-1)
tab[h]=c;
else
cout << "no niestety, nie udalo sie wstawic " <<endl; //"I couldn't map the element"
}
}
int wyszukaj(char *tab,int max, char c) // search an element
{
int i=modularnie(c, max);
int j=i;
if (tab[i]== '\0')
return -1;
while (tab[i]==c)
{
i=(i+1)%max;
if((i==j)||(tab[i]== '\0'))
return -1;
}
return i;
}
int usun(char *tab,int max, char c) // remove an element
{
int r,j,i=wyszukaj(tab,max,c);
j=i;
if (i==-1)
return -1;
tab[i]= '\0';
while (tab[(++i)%max]!= '\0')
{
i%=max;
r=modularnie(tab[i],max);
if (((i<r)&&(r<=j)) || ((r<=j)&&(j<i)) || ((j<i)&&(i<r)))
{
tab[j]=tab[i];
tab[i]= '\0';
j=i;
continue;
}
}
return 0;
}
int main()
{
srand( time( NULL ) );
int ile;
cout << "podaj wielkosc tablicy: "; //"Type the size of the table"
cin >> ile;
char* tab; // EDITED
tab=new char(ile);
for (int n=0; n<ile; n++)
{
tab[n]= '\0';
}
char e;
for (int i=0; i<ile; i++)
{
e='!'+rand()%127;
dodaj(tab, ile, e);
}
for(int j=0; j<ile; j++)
{
cout << j << ", " << tab[j] << endl;
}
return 0;
}

Building a 2D array class from a 1D array class in C++

in my C++ class we are finally getting conceptually fairly deep (well, relatively!) and I'm struggling with building a class from a previous class.
Here is my first class header, which builds partially filled array objects. To my knowledge, it is fully functional:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 50;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(const int init[], int used);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray();
int Search(ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
void DeleteRepeats();
int NumUsed();
void Sort();
void Reverse();
string ErrorDescr(int failCode);
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& operator [] (ITEM_TYPE x);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And here are the class functions:
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(const int init[], int used)
{
numUsed = used;
for(int i=0; i<numUsed; i++)
{
a[i]=init[i];
}
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray()
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
return i;
}
return -1;
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(numUsed<MAX)
a[numUsed++] = appendMe;
else
return 1;
return 0;
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[shiftHere] = save;
return 0;
}
else
return 2;
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[shiftHere];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 0;
}
else
return 2;
}
//Takes a number and a position and inserts the number before that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else
{
numUsed++;
ShiftRight(insertHere);
a[insertHere] = insertThis;
}
return 0;
}
//Takes a number and a position and inserts the number after that position in the array shifting the elements to the right
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else if(numUsed>=MAX)
return 1;
else
{
numUsed++;
ShiftRight(insertHere+1);
a[insertHere+1] = insertThis;
}
return 0;
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
if(deleteHere <= numUsed)
{
ShiftLeft(deleteHere);
numUsed--;
return 0;
}
else
return 2;
}
//Deletes repeated elements in the array and replaces the with 0
void PartialArray::DeleteRepeats()
{
for(int i=0;i<numUsed;i++)
{
ITEM_TYPE n=a[i];
for(int j=i+1; j<numUsed;j++)
{
if(n == a[j])
{
Delete(j);
j--;
}
}
}
}
//Returns number of interesting elements in the array
int PartialArray::NumUsed()
{
return numUsed;
}
//Utilizes a bubble sort algorithm
void PartialArray::Sort()
{
bool swap = true;
int j = 0;
int save;
while (swap==true)
{
swap = false;
j++;
for (int i = 0; i < numUsed - j; i++)
{
if (a[i] > a[i + 1])
{
save = a[i];
a[i] = a[i + 1];
a[i + 1] = save;
swap = true;
}
}
}
}
void PartialArray::Reverse()
{
for(int i=0;i<numUsed-1;i++)
{
ITEM_TYPE save = a[numUsed-1];
ShiftRight(i);
a[i] = save;
}
}
//Returns the appropriate error description for a particular fail code
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case -1:
return "ERROR: item not found";
break;
case 1:
return "ERROR: array is full";
break;
case 2:
return "ERROR: unused index";
break;
default:
return "UNKNOWN ERROR";
break;
}
}
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& PartialArray::operator [](ITEM_TYPE x)
{
return a[x];
}
Now, here is where things have gotten tricky. To build the two dimensional array class, I'm supposed to create an array of arrays. I'm at a loss as to how I should go about this, and after tinkering and googling for a few hours I've only become more confused. Specifically, the <<, [], and [](constant version) operators and the TwoDArray constructor have thrown me for a loop, and I'm stuck without much sense of what to do next. Here is the TwoD header file:
#ifndef TWODARRAY_H
#define TWODARRAY_H
#include "partialarray.h"
#include <iostream>
#include <string.h>
typedef int ITEM_TYPE;
class TwoDArray
{
friend ostream& operator << (ostream &outs, const TwoDArray& printMe);
public:
//ctors:
TwoDArray();
//member functions:
//PartialArray& operator [](int index); //[ ] operator for the TwoDArray object
//PartialArray operator [](int index) const; //[ ] operator for the TwoDArray object (const version)
int Append(int appendMe, int row);
int InsertBefore(int insertMe, int row, int column);
int InsertAfter(int insertMe, int row, int column);
int Delete(int row, int column);
bool Search(ITEM_TYPE key, int &row, int &column);
private:
//member vars:
PartialArray a[MAX];
};
#endif // TWODARRAY_H
And this is what I've tried to define thus far:
TwoDArray::TwoDArray()
{
const int array0[]= {0};
PartialArray array(array0, MAX);
}
ostream& operator << (ostream &outs, const TwoDArray& printMe)
{
for(int i=0;i<MAX;i++)
{
outs << printMe.a[i];
}
return outs;
}
Ideally, the << operator will print an m by n array of items.

Circular DeQueue implementation error

Basically a dynamic array, which has circular rotation when is full. You have access to every element and you can change it's value, however you can insert and remove only from both ends.(constant time). Most of the methods seem to be working fine, however at certain "push" numbers I get wrong output.
For example first input is 1,2,3 then I insert 4 at the end. Next output is: 2,3,4 However after I insert 5 at the end the output is 2, 3, 5
I have no idea what is causing this. I am posting the entire source code below (atleast the functions which have to do with the tests where the error must hide). There is some documentation in the file and an example of the error in case I haven't explained things clearly.
#include <iostream>
using namespace std;
template <typename Object>
class ArrayVector {
private:
int capacity; // capacity
int sz; // number of elements
Object* a;
int f; // start of the indexes
int b; // end of the indexes
public:
ArrayVector(int initCap);
~ArrayVector();
int size() const { return sz; }
bool isEmpty() const { return size() == 0; }
Object elemAtRank(int r);
void pushBack( const Object& e);
void pushFront(const Object& e);
void popBack();
void popFront();
};
template <typename Object> // constructor
ArrayVector<Object>::
ArrayVector(int initCap) {
capacity = initCap;
sz = 0;
a = new Object[capacity];
f = 0;
b = 0;
}
template <typename Object> // gets the element at a certain rank
Object ArrayVector<Object>:: elemAtRank(int r)
{
return a[(f + r) % sz]; // starting position in real array + r % number of elements
}
template <typename Object>
void ArrayVector<Object>:: pushBack( const Object& e)
{
if(sz == capacity && sz > 0) // if the array is full time to spin it
{
if(f == capacity){ // Handles the front.
f = 0; // if the front is equal to the capacity
// set it to zero, else increment
}else{
f++;
}
if(b == capacity){ //Handles the back
b = 0; //if the back is equal to the capacity
// cout<< "SC insert "<< e << " at "<< b <<endl;
a[b] = e;
}else{ // set it to zero, else increment
a[b] = e;
// cout<< "SC insert "<< e << " at "<< b <<endl;
b++;
}
}else{
a[b] = e;
// cout<< "insert "<< e << " at "<< b <<endl;
b++;
sz++;
}
}
template <typename Object>
void ArrayVector<Object>:: pushFront( const Object& e)
{
if(f == 0){
f = capacity-1;
}else{
f--;
}
a[f] = e;
if(sz< capacity)
sz++;
}
int main()
{
// Fill array and print it
cout << "Fill with numbers" << endl;
ArrayVector<int> asd(3);
asd.pushBack(1);
asd.pushBack(2);
asd.pushBack(3);
for(int i =0; i < asd.size(); i++)
cout << asd.elemAtRank(i) << endl;
//Test if it spins
cout << "BEGIN Spin TEST " << endl;
asd.pushBack(4);
cout << "First test is ok" << endl;
for(int i =0; i < asd.size(); i++)
cout << asd.elemAtRank(i) << endl;
// here the error comes
asd.pushBack(5);
cout << "On the second iteration things crash and burn" << endl;
for(int i =0; i < asd.size(); i++)
cout << asd.elemAtRank(i) << endl;
return 0;
}
In addition to your insertion times not matching your desired requirements, your issue is here:
template <typename Object>
void ArrayVector<Object>:: pushFront( const Object& e)
{
if(f == 0)
{
f = capacity-1;
}
else
{
f--;
}
a[f] = e; // problem lies here!
if(sz < capacity)
sz++;
}
You are figuring out where to do the insert, but you are not pushing the other elements around the vector; that is, you are just overwriting the element at the insertion point. If you wanted to push it onto the front, you would need to copy the other elements over 1 position each and then do your insert. A better solution (which would match your constant insertion time requirement) would be to implement it as a double-linked list. Pushing onto the ends would simply require the following pseudo-code:
void push_front(const Object& o)
{
if (size == capacity)
l.pop_back();
l.push_front(o);
}
If you really must use a contiguous memory block, you will not get constant-time insertion, but it would look like this:
// Assumptions: 0 is always the front, capacity-1 is always the maximum back
template <typename Object>
void ArrayVector<Object>:: pushFront( const Object& e)
{
// assume capacity > 0, move all the elements to the right one slot
for (int i = capacity - 1; i > 0; --i)
{
a[i] = a[i - 1];
}
a[0] = e;
if(sz < capacity)
sz++;
}

Function-call operator overload & destructor help

I think my destructor is good now... but still not sure how to call print_set from within the operator() overload.
It outputs as it should, but I feel like there is an easy way to just call print_set from within the function call overload... can't seem to get things how I want them..
Header file:
/**
* disjoint_sets class declaration
*
*/
#include<ostream>
#include<string>
#include<list>
class disjoint_sets
{
public:
disjoint_sets(int n); //n is the maximum int that can be in a set, so arrays need to be of size n+1
~disjoint_sets();
bool make_set(int n);
int find_set(int u);
bool union_set(int u, int v);
void print_set(std::ostream& out, int u); //e.g. { 1, 2, 4, 8, 10, }
operator std::string(); //e.g. "{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }"
private:
typedef std::list<int>* listptr;
int* p; //parent array
int* rank; //rank array
listptr* set; //array of pointers. Each set[i] is a pointer is to a list<int> containing the integers in the i'th set
int size; //the size i.e. maximum int that can be in a set
};
Implementation:
/**
* disjoint_sets class implementation
*
*/
#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <list>
#include "disjoint.hpp"
/*********************
* CONSTRUCTOR
*********************/
disjoint_sets::disjoint_sets(int n)
{
size = n;
// initialize all arrays to same size (n+1)
p = new int[n+1];
rank = new int[n+1];
set = new listptr[n+1];
// loop through set (array of pointers) and initialize
// each element to an empty list
for (int i(1); i <= n; i++)
{
set[i] = new std::list<int>;
}
}
/*********************
* DESTRUCTOR
*********************/
disjoint_sets::~disjoint_sets()
{
delete[] p;
delete[] rank;
// delete each element in the set first, then delete the set.
for(int i(1); i<size+1; i++)
{
set[i]->clear();
}
delete[] set;
}
/*********************
* MAKE_SET
*********************/
bool disjoint_sets::make_set(int n)
{
// if parent already exists
if (p[n] != 0)
{
return false;
}
// else we need to make a set
else
{
// make itself the parent
p[n] = n;
// use push_front to add the int to front of set
set[n]->push_front(n);
return true;
}
}
/*********************
* FIND_SET
***********************/
int disjoint_sets::find_set(int u)
{
while (u != p[u])
{
u = p[u];
}
// returns parent
return u;
}
/*********************
* UNION_SET
*********************/
bool disjoint_sets::union_set(int u, int v)
{
// assign parents to u, v
u = find_set(u);
v = find_set(v);
// return false if parent is 0, list is empty
if (u == 0 or v == 0)
{
return false;
}
// if u's height is less than v's (not in same set)
if (rank[u] < rank[v])
{
// point u's parent to v (merge them)
p[u] = v;
// splice u out
(*set[v]).splice((*set[v]).end(), (*set[u]));
return true;
}
// u's height is greater than or equal to v's height
else
{
// set v's parent to u
p[v] = u;
// splice v out
(*set[u]).splice((*set[u]).end(), (*set[v]));
return true;
}
// if ranks are equal
if (rank[u] == rank[v])
{
// increment rank of u
rank[u]++;
return true;
}
}
/*********************
* PRINT_SET
*********************/
void disjoint_sets::print_set(std::ostream& out, int u)
{
// begin brace for set
out << "{ ";
// loop through with iter, seperate with comma
for (std::list<int>::iterator iter((*set[u]).begin()); iter != (*set[u]).end(); iter++)
{
out << *iter << ", ";
}
// end brace for set
out << "}";
}
/*********************
* STRING CONVERSION
*********************/
disjoint_sets::operator std::string()
{
// sstream variable
std::stringstream text;
// pointer to int array
int *test;
test = new int[size+1];
// opening paren
text << "{ ";
// start main loop through the array
for (int i(1); i <= (size + 1); i++)
{
// if the root is empty
if (test[find_set(i)] == 0)
{
// set to anything != 0?
test[find_set(i)] = 10;
// check if list is empty
if (set[i]->empty())
{
text << "";
}
else
{
// individual set opening parenthesis
text << "{ ";
// use iterator to loop through and load up the stringstream, separate w/ comma
for (std::list<int>::iterator iter((*set[i]).begin()); iter != (*set[i]).end(); iter++)
{
text << *iter << ", ";
}
// individual set closing parenthesis w/ proper punctuation
text << "}, ";
}
}
}
// closing parenthesis
text << "}";
delete[] test;
return text.str();
}
Driver:
#include<iostream>
#include "disjoint.hpp"
int main()
{
using namespace std;
disjoint_sets ds(12);
for( int i=1; i <= 10; ++i)
ds.make_set(i);
ds.union_set(1,2);
ds.union_set(2,4);
ds.union_set(1,8);
ds.union_set(3,6);
ds.union_set(2,10);
//{ { 1, 2, 4, 8, 10, }, { 3, 6, }, { 5, }, { 7, }, { 9, }, }
cout << string(ds) << endl;
}
Just focusing on the destructor:
// delete[] set; // need special conditions for this?
Yes, you need to delete each element in the set first and then delete the set. Use std::shared_ptr if you are not interested to do the memory management.
As a hint: You might get better answers if you ask concrete questions.