School Commit Init
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
|
||||
#include <iostream>
|
||||
#include "Matrix.h"
|
||||
#include "ExtendedTest.h"
|
||||
#include "ShortTest.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
|
||||
testAll();
|
||||
testAllExtended();
|
||||
cout << "Test End" << endl;
|
||||
system("pause");
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
#include <assert.h>
|
||||
#include "Matrix.h"
|
||||
#include "ExtendedTest.h"
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void testCreate() {
|
||||
cout << "Test create" << endl;
|
||||
Matrix m(10, 10);
|
||||
assert(m.nrLines() == 10);
|
||||
assert(m.nrColumns() == 10);
|
||||
for (int i = 0; i < m.nrLines(); i++)
|
||||
for (int j = 0; j < m.nrColumns(); j++)
|
||||
assert(m.element(i, j) == NULL_TELEM);
|
||||
}
|
||||
|
||||
void testModify() {
|
||||
cout << "Test modify" << endl;
|
||||
Matrix m(10, 10);
|
||||
for (int j = 0; j < m.nrColumns(); j++)
|
||||
m.modify(4, j, 3);
|
||||
for (int i = 0; i < m.nrLines(); i++)
|
||||
for (int j = 0; j < m.nrColumns(); j++)
|
||||
if (i == 4)
|
||||
assert(m.element(i, j) == 3);
|
||||
else
|
||||
assert(m.element(i, j) == NULL_TELEM);
|
||||
}
|
||||
|
||||
void testQuantity() {
|
||||
cout << "Test quantity" << endl;
|
||||
Matrix m(200, 300);
|
||||
for (int i = m.nrLines() / 2; i < m.nrLines(); i++) {
|
||||
for (int j = 0; j <= m.nrColumns() / 2; j++)
|
||||
{
|
||||
int v1 = j;
|
||||
int v2 = m.nrColumns() - v1 - 1;
|
||||
if (i % 2 == 0 && v1 % 2 == 0)
|
||||
m.modify(i, v1, i*v1);
|
||||
else
|
||||
if (v1 % 3 == 0)
|
||||
m.modify(i, v1, i + v1);
|
||||
if (i % 2 == 0 && v2 % 2 == 0)
|
||||
m.modify(i, v2, i*v2);
|
||||
else
|
||||
if (v2 % 3 == 0)
|
||||
m.modify(i, v2, i + v2);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i <= m.nrLines() / 2; i++) {
|
||||
for (int j = 0; j <= m.nrColumns() / 2; j++)
|
||||
{
|
||||
int v1 = j;
|
||||
int v2 = m.nrColumns() - v1 - 1;
|
||||
if (i % 2 == 0 && v1 % 2 == 0)
|
||||
m.modify(i, v1, i*v1);
|
||||
else
|
||||
if (v1 % 3 == 0)
|
||||
m.modify(i, v1, i + v1);
|
||||
if (i % 2 == 0 && v2 % 2 == 0)
|
||||
m.modify(i, v2, i*v2);
|
||||
else
|
||||
if (v2 % 3 == 0)
|
||||
m.modify(i, v2, i + v2);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < m.nrLines(); i++)
|
||||
for (int j = 0; j < m.nrColumns(); j++)
|
||||
if (i % 2 == 0 && j % 2 == 0)
|
||||
assert(m.element(i, j) == i * j);
|
||||
else
|
||||
if (j % 3 == 0)
|
||||
assert(m.element(i, j) == i + j);
|
||||
else assert(m.element(i, j) == NULL_TELEM);
|
||||
}
|
||||
|
||||
void testExceptions() {
|
||||
cout << "Test exceptions" << endl;
|
||||
Matrix m(10, 10);
|
||||
try {
|
||||
m.element(-10, 0);
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
m.modify(12, 0, 1);
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
assert(m.nrLines());
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void testMix() {
|
||||
cout << "Test mix" << endl;
|
||||
int size = 2000;
|
||||
Matrix m(size/2, size);
|
||||
for (int i = 0; i < size/2; i++) {
|
||||
for (int j = 0; j < size; j++) {
|
||||
if (i == j) {
|
||||
m.modify(i, j, 11);
|
||||
}
|
||||
else if (i == 100 * j) {
|
||||
m.modify(i, j, 111);
|
||||
}
|
||||
else if ((i + j) % 1111 == 0) {
|
||||
m.modify(i, j, 1111);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < size/2; i++) {
|
||||
for (int j = 0; j < size; j++) {
|
||||
if (i == j) {
|
||||
TElem old = m.modify(i, j, NULL_TELEM);
|
||||
assert(old == 11);
|
||||
}
|
||||
else if (i == 100 * j) {
|
||||
TElem old = m.modify(i, j, -111);
|
||||
assert(old == 111);
|
||||
}
|
||||
else if ((i + j) % 1111 == 3) {
|
||||
m.modify(i, j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size/2; i++) {
|
||||
for (int j = 0; j < size; j++) {
|
||||
TElem e = m.element(i, j);
|
||||
if (i == j) {
|
||||
assert(e == NULL_TELEM);
|
||||
}
|
||||
else if (i == 100 * j) {
|
||||
assert(e == -111);
|
||||
}
|
||||
else if ((i + j) % 1111 == 3) {
|
||||
assert(e == 1);
|
||||
}
|
||||
else if ((i + j) % 1111 == 0) {
|
||||
assert(e == 1111);
|
||||
}
|
||||
else {
|
||||
assert(e == NULL_TELEM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testAllExtended() {
|
||||
testCreate();
|
||||
testModify();
|
||||
testQuantity();
|
||||
testMix();
|
||||
testExceptions();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "ExtendedTest.h"
|
||||
|
||||
void testAllExtended();
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "Matrix.h"
|
||||
#include <exception>
|
||||
using namespace std;
|
||||
|
||||
|
||||
Matrix::Matrix(int nrLines, int nrColumns) {
|
||||
// Theta(1)
|
||||
if (nrLines <= 0 || nrColumns <= 0) {
|
||||
throw exception();
|
||||
}
|
||||
this->numberOfLines = nrLines;
|
||||
this->numberOfColumns = nrColumns;
|
||||
this->values = new TElem[nrLines * nrColumns];
|
||||
this->lines = new int[nrLines * nrColumns];
|
||||
this->columns = new int[nrColumns+1];
|
||||
for (int i = 0; i < nrColumns+1; i++) {
|
||||
this->columns[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int Matrix::nrLines() const {
|
||||
// Theta(1)
|
||||
return this->numberOfLines;
|
||||
}
|
||||
|
||||
|
||||
int Matrix::nrColumns() const {
|
||||
// Theta(1)
|
||||
return this->numberOfColumns;
|
||||
}
|
||||
|
||||
|
||||
TElem Matrix::element(int i, int j) const {
|
||||
// Best: theta(1) | Worst: theta( nr of non-zero elements in the column) | Total: theta( nr of non-zero elements in the column)
|
||||
|
||||
if(i>=this->numberOfLines || j>=this->numberOfColumns || i<0 || j<0)
|
||||
throw exception();
|
||||
|
||||
for(int k=0;k<this->columns[j+1]-this->columns[j];k++){
|
||||
if(this->lines[k+this->columns[j]]==i)
|
||||
return this->values[k+this->columns[j]];
|
||||
}
|
||||
return NULL_TELEM;
|
||||
}
|
||||
|
||||
TElem Matrix::modify(int i, int j, TElem e) {
|
||||
// Best: theta(1) | Worst: theta( nr of rows + nr of non zero values + nr of non zero values in the column) | Total: theta( nr of rows + nr of non zero values + nr of non zero values in the column)
|
||||
|
||||
if(i>=this->numberOfLines || j>=this->numberOfColumns || i<0 || j<0)
|
||||
throw exception();
|
||||
|
||||
for(int k=0;k<this->columns[j+1]-this->columns[j];k++){
|
||||
if(this->lines[k+this->columns[j]]==i){
|
||||
swap(this->values[k+this->columns[j]],e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
for(int k=this->columns[this->numberOfColumns];k>this->columns[j];k--){
|
||||
swap(this->lines[k],this->lines[k-1]);
|
||||
swap(this->values[k],this->values[k-1]);
|
||||
}
|
||||
this->lines[this->columns[j]]=i;
|
||||
this->values[this->columns[j]]=e;
|
||||
for(int k=j+1;k<=this->numberOfColumns;k++)
|
||||
this->columns[k]++;
|
||||
return NULL_TELEM;
|
||||
}
|
||||
|
||||
void Matrix::setMainDiagonal(TElem e) {
|
||||
// Theta(min(nr of rows,nr of cols))
|
||||
int length = this->numberOfLines;
|
||||
if (this->numberOfColumns < this->numberOfLines) {
|
||||
length = this->numberOfColumns;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
this->modify(i, i, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
typedef int TElem;
|
||||
#define NULL_TELEM 0
|
||||
|
||||
class Matrix {
|
||||
|
||||
private:
|
||||
//TODO - Representation
|
||||
TElem* values;
|
||||
int* lines;
|
||||
int* columns;
|
||||
int numberOfLines;
|
||||
int numberOfColumns;
|
||||
|
||||
public:
|
||||
//constructor
|
||||
Matrix(int nrLines, int nrCols);
|
||||
|
||||
//returns the number of lines
|
||||
int nrLines() const;
|
||||
|
||||
//returns the number of columns
|
||||
int nrColumns() const;
|
||||
|
||||
//returns the element from line i and column j (indexing starts from 0)
|
||||
//throws exception if (i,j) is not a valid position in the Matrix
|
||||
TElem element(int i, int j) const;
|
||||
|
||||
//modifies the value from line i and column j
|
||||
//returns the previous value from the position
|
||||
//throws exception if (i,j) is not a valid position in the Matrix
|
||||
TElem modify(int i, int j, TElem e);
|
||||
|
||||
void setMainDiagonal(TElem e);
|
||||
|
||||
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <assert.h>
|
||||
#include "Matrix.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void testAll() {
|
||||
Matrix m(4, 4);
|
||||
assert(m.nrLines() == 4);
|
||||
assert(m.nrColumns() == 4);
|
||||
m.modify(1, 1, 5);
|
||||
assert(m.element(1, 1) == 5);
|
||||
TElem old = m.modify(1, 1, 6);
|
||||
assert(m.element(1, 2) == NULL_TELEM);
|
||||
assert(old == 5);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAll();
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "ExtendedTest.h"
|
||||
#include "ShortTest.h"
|
||||
|
||||
#include "SortedMap.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main() {
|
||||
testAll();
|
||||
testAllExtended();
|
||||
cout << "That's all!" << endl;
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,341 @@
|
||||
#include <exception>
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "SortedMap.h"
|
||||
#include "SMIterator.h"
|
||||
#include "ExtendedTest.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool increasing(TKey c1, TKey c2) {
|
||||
if (c1 <= c2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool decreasing(TKey c1, TKey c2) {
|
||||
if (c1 >= c2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void testIteratorSteps(SortedMap& m, Relation r) {
|
||||
SMIterator li = m.iterator();
|
||||
TElem elem = NULL_TPAIR;
|
||||
int count = 0;
|
||||
if (li.valid()) {
|
||||
elem = li.getCurrent();
|
||||
count++;
|
||||
li.next();
|
||||
}
|
||||
while (li.valid()) {
|
||||
TElem elem2 = li.getCurrent();
|
||||
assert(r(elem.first, elem2.first));
|
||||
elem = elem2;
|
||||
count++;
|
||||
li.next();
|
||||
}
|
||||
assert(count == m.size());
|
||||
}
|
||||
|
||||
void testCreate() {
|
||||
cout << "Test create" << endl;
|
||||
SortedMap sm(increasing);
|
||||
assert(sm.size() == 0);
|
||||
assert(sm.isEmpty());
|
||||
|
||||
SMIterator it = sm.iterator();
|
||||
it.first();
|
||||
assert(!it.valid());
|
||||
try {
|
||||
it.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it.getCurrent();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(sm.search(i) == NULL_TVALUE);
|
||||
}
|
||||
|
||||
for (int i = -10; i < 10; i++) {
|
||||
assert(sm.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void testSearch(Relation r) {
|
||||
cout << "Test search" << endl;
|
||||
SortedMap sm(r);
|
||||
int cMin = 0;
|
||||
int cMax = 10;
|
||||
try {
|
||||
for (int i = cMin; i <= cMax; i++) {
|
||||
sm.add(i, i + 1);
|
||||
}
|
||||
assert(true);
|
||||
} catch (exception&) {
|
||||
assert(false);
|
||||
}
|
||||
int intervalDim = 10;
|
||||
for (int i = cMin; i <= cMax; i++) {
|
||||
assert(sm.search(i) == i + 1);
|
||||
}
|
||||
testIteratorSteps(sm, r);
|
||||
for (int i = cMin - intervalDim; i < cMin; i++) {
|
||||
assert(sm.search(i) == NULL_TVALUE);
|
||||
}
|
||||
for (int i = cMax + 1; i < cMax + intervalDim; i++) {
|
||||
assert(sm.search(i) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void testSearch() {
|
||||
testSearch(increasing);
|
||||
testSearch(decreasing);
|
||||
}
|
||||
|
||||
vector<int> keysInRandomOrder(int cMin, int cMax) {
|
||||
vector<int> keys;
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
keys.push_back(c);
|
||||
}
|
||||
int n = keys.size();
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
int j = i + rand() % (n - i);
|
||||
swap(keys[i], keys[j]);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
void populateSMEmpty(SortedMap& sm, int cMin, int cMax) {
|
||||
vector<int> keys = keysInRandomOrder(cMin, cMax);
|
||||
int n = keys.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
assert(sm.add(keys[i], keys[i]) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void rePopulateSMShift(SortedMap& sm, int cMin, int cMax, int shift) {
|
||||
vector<int> keys = keysInRandomOrder(cMin, cMax);
|
||||
int n = keys.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
assert(sm.add(keys[i], keys[i] - shift) == keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void populateSMShift(SortedMap& sm, int cMin, int cMax, int shift) {
|
||||
vector<int> keys = keysInRandomOrder(cMin, cMax);
|
||||
int n = keys.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
sm.add(keys[i], keys[i] - shift);
|
||||
}
|
||||
}
|
||||
|
||||
void testAddAndSearch(Relation r) {
|
||||
cout << "Test add and search" << endl;
|
||||
SortedMap sm(r);
|
||||
int cMin = 100;
|
||||
int cMax = 200;
|
||||
|
||||
populateSMEmpty(sm, cMin, cMax);
|
||||
testIteratorSteps(sm, r);
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
assert(sm.search(c) == c);
|
||||
}
|
||||
assert(sm.size() == (cMax - cMin + 1));
|
||||
|
||||
rePopulateSMShift(sm, cMin, cMax, 1);
|
||||
assert(sm.size() == (cMax - cMin + 1));
|
||||
testIteratorSteps(sm, r);
|
||||
populateSMShift(sm, 2 * cMax, 3 * cMax, 2 * cMax - cMin);
|
||||
for (int c = 2 * cMax; c <= 3 * cMax; c++) {
|
||||
assert(sm.search(c) == c - 2 * cMax + cMin);
|
||||
}
|
||||
testIteratorSteps(sm, r);
|
||||
assert(sm.size() == (cMax - cMin + 1) + (cMax + 1));
|
||||
|
||||
SMIterator it = sm.iterator();
|
||||
it.first();
|
||||
if (it.valid()) {
|
||||
TKey cPrec = it.getCurrent().first;
|
||||
assert(sm.search(cPrec) != NULL_TVALUE);
|
||||
it.next();
|
||||
while (it.valid()) {
|
||||
TKey c = it.getCurrent().first;
|
||||
assert(r(cPrec, c));
|
||||
assert(sm.search(c) != NULL_TVALUE);
|
||||
cPrec = c;
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testAdd() {
|
||||
testAddAndSearch(increasing);
|
||||
testAddAndSearch(decreasing);
|
||||
}
|
||||
|
||||
void testRemoveAndSearch(Relation r) {
|
||||
cout << "Test remove and search" << endl;
|
||||
SortedMap sm(r);
|
||||
int cMin = 10;
|
||||
int cMax = 20;
|
||||
populateSMEmpty(sm, cMin, cMax);
|
||||
testIteratorSteps(sm, r);
|
||||
for (int c = cMax + 1; c <= 2 * cMax; c++) {
|
||||
assert(sm.remove(c) == NULL_TVALUE);
|
||||
testIteratorSteps(sm, r);
|
||||
}
|
||||
int dim = cMax - cMin + 1;
|
||||
assert(sm.size() == dim);
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
assert(sm.remove(c) == c);
|
||||
assert(sm.search(c) == NULL_TVALUE);
|
||||
|
||||
SMIterator it = sm.iterator();
|
||||
it.first();
|
||||
if (it.valid()) {
|
||||
TKey cPrec = it.getCurrent().first;
|
||||
it.next();
|
||||
while (it.valid()) {
|
||||
TKey c = it.getCurrent().first;
|
||||
assert(r(cPrec, c));
|
||||
cPrec = c;
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
|
||||
dim--;
|
||||
assert(sm.size() == dim);
|
||||
|
||||
}
|
||||
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
assert(sm.remove(c) == NULL_TVALUE);
|
||||
}
|
||||
assert(sm.isEmpty());
|
||||
assert(sm.size() == 0);
|
||||
|
||||
}
|
||||
|
||||
void testRemove() {
|
||||
testRemoveAndSearch(increasing);
|
||||
testRemoveAndSearch(decreasing);
|
||||
}
|
||||
|
||||
void testIterator(Relation r) {
|
||||
cout << "Test iterator" << endl;
|
||||
SortedMap sm(r);
|
||||
SMIterator it = sm.iterator();
|
||||
assert(!it.valid());
|
||||
it.first();
|
||||
assert(!it.valid());
|
||||
int cMin = 100;
|
||||
int cMax = 300;
|
||||
vector<int> keys = keysInRandomOrder(cMin, cMax);
|
||||
int n = keys.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
assert(sm.add(keys[i], keys[n - i - 1]) == NULL_TVALUE);
|
||||
}
|
||||
|
||||
SMIterator itSM = sm.iterator();
|
||||
assert(itSM.valid());
|
||||
itSM.first();
|
||||
assert(itSM.valid());
|
||||
|
||||
TKey cPrec = itSM.getCurrent().first;
|
||||
for (int i=1; i<100; i++){
|
||||
assert(cPrec == itSM.getCurrent().first);
|
||||
}
|
||||
itSM.next();
|
||||
while (itSM.valid()) {
|
||||
TKey c = itSM.getCurrent().first;
|
||||
assert(cMin <= c && c <= cMax);
|
||||
assert(sm.search(c) != NULL_TVALUE);
|
||||
assert(r(cPrec, c));
|
||||
cPrec = c;
|
||||
itSM.next();
|
||||
}
|
||||
}
|
||||
|
||||
void testQuantity(){
|
||||
cout << "Test quantity" << endl;
|
||||
SortedMap sm(increasing);
|
||||
int cMin = -3000;
|
||||
int cMax = 3000;
|
||||
vector<int> keys = keysInRandomOrder(cMin, cMax);
|
||||
populateSMEmpty(sm, cMin, cMax);
|
||||
for (int c = cMin; c <= cMax; c++){
|
||||
assert(sm.search(c) == c);
|
||||
}
|
||||
testIteratorSteps(sm, increasing);
|
||||
assert(sm.size() == cMax - cMin + 1);
|
||||
SMIterator it = sm.iterator();
|
||||
assert(it.valid());
|
||||
it.first();
|
||||
assert(it.valid());
|
||||
for (int i = 0; i < sm.size(); i++) {
|
||||
it.next();
|
||||
}
|
||||
assert(!it.valid());
|
||||
it.first();
|
||||
while (it.valid()){
|
||||
TKey c = it.getCurrent().first;
|
||||
assert(sm.search(c) == c);
|
||||
TValue v = it.getCurrent().second;
|
||||
assert(c == v);
|
||||
it.next();
|
||||
}
|
||||
assert(!it.valid());
|
||||
for (int c = cMin-100; c <= cMax+100; c++){
|
||||
sm.remove(c);
|
||||
assert(sm.search(c) == NULL_TVALUE);
|
||||
testIteratorSteps(sm, increasing);
|
||||
}
|
||||
assert(sm.size() == 0);
|
||||
assert(sm.isEmpty());
|
||||
}
|
||||
|
||||
void testIterator() {
|
||||
testIterator(increasing);
|
||||
testIterator(decreasing);
|
||||
}
|
||||
|
||||
void testExtra(){
|
||||
cout << "Test extra" << endl;
|
||||
SortedMap sm(increasing);
|
||||
sm.add(1, 1);
|
||||
sm.add(2, 2);
|
||||
sm.add(3, 3);
|
||||
sm.add(4, 3);
|
||||
vector<TValue> v = sm.valueBag();
|
||||
assert(v.size() == 3);
|
||||
assert(v[0] == 1);
|
||||
assert(v[1] == 2);
|
||||
assert(v[2] == 3);
|
||||
}
|
||||
|
||||
void testAllExtended() {
|
||||
testCreate();
|
||||
testAdd();
|
||||
testSearch();
|
||||
testRemove();
|
||||
testIterator();
|
||||
testQuantity();
|
||||
testExtra();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
void testAllExtended();
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "SMIterator.h"
|
||||
#include "SortedMap.h"
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
|
||||
SMIterator::SMIterator(const SortedMap& m) : map(m){
|
||||
//Complexity: O(1)
|
||||
this->current = this->map.head;
|
||||
|
||||
}
|
||||
|
||||
void SMIterator::first(){
|
||||
//Complexity: O(1)
|
||||
this->current = this->map.head;
|
||||
}
|
||||
|
||||
void SMIterator::next(){
|
||||
//Complexity: O(1)
|
||||
if (this->current == nullptr)
|
||||
throw exception();
|
||||
this->current = this->current->next;
|
||||
}
|
||||
|
||||
bool SMIterator::valid() const{
|
||||
//Complexity: O(1)
|
||||
if(this->current == nullptr)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
TElem SMIterator::getCurrent() const{
|
||||
//Complexity: O(1)
|
||||
if(this->current==nullptr)
|
||||
throw exception();
|
||||
return this->current->element;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "SortedMap.h"
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
class SMIterator{
|
||||
friend class SortedMap;
|
||||
private:
|
||||
const SortedMap& map;
|
||||
SMIterator(const SortedMap& mapionar);
|
||||
|
||||
//TODO - Representation
|
||||
Node* current;
|
||||
|
||||
public:
|
||||
void first();
|
||||
void next();
|
||||
bool valid() const;
|
||||
TElem getCurrent() const;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "SortedMap.h"
|
||||
#include "SMIterator.h"
|
||||
#include "ShortTest.h"
|
||||
#include <exception>
|
||||
using namespace std;
|
||||
|
||||
bool relatie1(TKey cheie1, TKey cheie2) {
|
||||
if (cheie1 <= cheie2) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void testAll(){
|
||||
SortedMap sm(relatie1);
|
||||
assert(sm.size() == 0);
|
||||
assert(sm.isEmpty());
|
||||
sm.add(1,2);
|
||||
assert(sm.size() == 1);
|
||||
assert(!sm.isEmpty());
|
||||
assert(sm.search(1)!=NULL_TVALUE);
|
||||
TValue v =sm.add(1,3);
|
||||
assert(v == 2);
|
||||
assert(sm.search(1) == 3);
|
||||
SMIterator it = sm.iterator();
|
||||
it.first();
|
||||
while (it.valid()){
|
||||
TElem e = it.getCurrent();
|
||||
assert(e.second != NULL_TVALUE);
|
||||
it.next();
|
||||
}
|
||||
assert(sm.remove(1) == 3);
|
||||
assert(sm.isEmpty());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAll();
|
||||
@@ -0,0 +1,130 @@
|
||||
#include "SMIterator.h"
|
||||
#include "SortedMap.h"
|
||||
#include <exception>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
SortedMap::SortedMap(Relation r) {
|
||||
//Complexity: O(1)
|
||||
this->relation = r;
|
||||
this->head = nullptr;
|
||||
this->length = 0;
|
||||
}
|
||||
|
||||
TValue SortedMap::add(TKey k, TValue v) {
|
||||
//Complexity: O(n) - average/worst O(1) - best
|
||||
if (this->head == nullptr){
|
||||
this->head = new Node(pair<TKey, TValue>(k, v));
|
||||
this->length++;
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
if (this->head->element.first == k){
|
||||
TValue value = this->head->element.second;
|
||||
this->head->element.second = v;
|
||||
return value;
|
||||
}
|
||||
if(this->relation(k, this->head->element.first)){
|
||||
Node* new_node = new Node(pair<TKey, TValue>(k, v));
|
||||
new_node->next = this->head;
|
||||
this->head = new_node;
|
||||
this->length++;
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
Node* previous_node = this->head;
|
||||
Node* current_node = this->head->next;
|
||||
for(int i = 0; i < this->length-1; i++){
|
||||
if (current_node->element.first == k){
|
||||
TValue value = current_node->element.second;
|
||||
current_node->element.second = v;
|
||||
return value;
|
||||
}
|
||||
if (this->relation(k, current_node->element.first)){
|
||||
Node* new_node = new Node(pair<TKey, TValue>(k, v));
|
||||
new_node->next = current_node;
|
||||
previous_node->next = new_node;
|
||||
this->length++;
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
previous_node = current_node;
|
||||
current_node = current_node->next;
|
||||
}
|
||||
previous_node->next = new Node(pair<TKey, TValue>(k, v));
|
||||
this->length++;
|
||||
return NULL_TVALUE;
|
||||
|
||||
}
|
||||
|
||||
TValue SortedMap::search(TKey k) const {
|
||||
//Complexity: O(n) - average/worst O(1) - best
|
||||
Node* current_node = this->head;
|
||||
for(int i = 0; i< this->length; i++){
|
||||
if (current_node->element.first == k)
|
||||
return current_node->element.second;
|
||||
current_node = current_node->next;
|
||||
}
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
|
||||
TValue SortedMap::remove(TKey k) {
|
||||
//Complexity: O(n) - average/worst O(1) - best
|
||||
if(this->head!=nullptr && this->head->element.first == k){
|
||||
Node* new_head = this->head->next;
|
||||
TValue value = this->head->element.second;
|
||||
delete this->head;
|
||||
this->head = new_head;
|
||||
this->length--;
|
||||
return value;
|
||||
}
|
||||
Node* current_node = this->head;
|
||||
for(int i = 1; i< this->length; i++){
|
||||
if (current_node->next->element.first == k){
|
||||
Node* removed_node = current_node->next;
|
||||
TValue value = removed_node->element.second;
|
||||
current_node->next = current_node->next->next;
|
||||
delete removed_node;
|
||||
this->length--;
|
||||
return value;
|
||||
}
|
||||
current_node = current_node->next;
|
||||
}
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
|
||||
int SortedMap::size() const {
|
||||
//Complexity: O(1)
|
||||
return this->length;
|
||||
}
|
||||
|
||||
bool SortedMap::isEmpty() const {
|
||||
//Complexity: O(1)
|
||||
if (this->length == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
SMIterator SortedMap::iterator() const {
|
||||
//Complexity: O(1)
|
||||
return SMIterator(*this);
|
||||
}
|
||||
|
||||
SortedMap::~SortedMap() {
|
||||
//Complexity: O(n)
|
||||
Node* current_node = this->head;
|
||||
for(int i = 0; i < this->length; i++){
|
||||
Node* next_node = current_node->next;
|
||||
delete current_node;
|
||||
current_node = next_node;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TValue> SortedMap::valueBag() {
|
||||
//Complexity: O(n*m) - average/worst O(n) - best
|
||||
vector<TValue> values;
|
||||
Node* current_node = this->head;
|
||||
for(int i = 0; i < this->length; i++){
|
||||
if (find(values.begin(), values.end(), current_node->element.second) == values.end())
|
||||
values.push_back(current_node->element.second);
|
||||
current_node = current_node->next;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
//DO NOT INCLUDE SORTEDMAPITERATOR
|
||||
#include <vector>
|
||||
//DO NOT CHANGE THIS PART
|
||||
typedef int TKey;
|
||||
typedef int TValue;
|
||||
#include <utility>
|
||||
typedef std::pair<TKey, TValue> TElem;
|
||||
#define NULL_TVALUE -111111
|
||||
#define NULL_TPAIR pair<TKey, TValue>(-111111, -111111);
|
||||
class SMIterator;
|
||||
typedef bool(*Relation)(TKey, TKey);
|
||||
|
||||
class Node {
|
||||
public:
|
||||
TElem element;
|
||||
Node* next;
|
||||
Node(TElem e) {
|
||||
element = e;
|
||||
next = nullptr;
|
||||
}
|
||||
Node(TElem e, Node* n) {
|
||||
element = e;
|
||||
next = n;
|
||||
}
|
||||
bool operator==(Node* n) {
|
||||
return this->element.first == n->element.first;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SortedMap {
|
||||
friend class SMIterator;
|
||||
private:
|
||||
//TODO - Representation
|
||||
Node* head;
|
||||
Relation relation;
|
||||
int length;
|
||||
public:
|
||||
|
||||
// implicit constructor
|
||||
SortedMap(Relation r);
|
||||
|
||||
// adds a pair (key,value) to the map
|
||||
//if the key already exists in the map, then the value associated to the key is replaced by the new value and the old value is returned
|
||||
//if the key SMes not exist, a new pair is added and the value null is returned
|
||||
TValue add(TKey c, TValue v);
|
||||
|
||||
//searches for the key and returns the value associated with the key if the map contains the key or null: NULL_TVALUE otherwise
|
||||
TValue search(TKey c) const;
|
||||
|
||||
|
||||
//removes a key from the map and returns the value associated with the key if the key existed ot null: NULL_TVALUE otherwise
|
||||
TValue remove(TKey c);
|
||||
|
||||
//returns the number of pairs (key,value) from the map
|
||||
int size() const;
|
||||
|
||||
//checks whether the map is empty or not
|
||||
bool isEmpty() const;
|
||||
|
||||
// return the iterator for the map
|
||||
// the iterator will return the keys following the order given by the relation
|
||||
SMIterator iterator() const;
|
||||
|
||||
// destructor
|
||||
~SortedMap();
|
||||
|
||||
std::vector<TValue> valueBag();
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "ShortTest.h"
|
||||
#include "ExtendedTest.h"
|
||||
|
||||
int main(){
|
||||
testAll();
|
||||
testAllExtended();
|
||||
std::cout<<"Finished IL Tests!"<<std::endl;
|
||||
system("pause");
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
#include "ExtendedTest.h"
|
||||
#include <assert.h>
|
||||
#include <exception>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "ListIterator.h"
|
||||
#include "SortedIndexedList.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
//order relation - ascending
|
||||
bool asc(TComp c1, TComp c2) {
|
||||
if (c1 <= c2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//order relation - descending
|
||||
bool desc(TComp c1, TComp c2) {
|
||||
if (c1 >= c2) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void testIteratorSteps(SortedIndexedList& list, Relation r) {
|
||||
int count = 0;
|
||||
ListIterator li = list.iterator();
|
||||
TComp prev = li.getCurrent();
|
||||
if (li.valid()) {
|
||||
count++;
|
||||
li.next();
|
||||
}
|
||||
while (li.valid()) {
|
||||
TComp current = li.getCurrent();
|
||||
assert(r(prev, current));
|
||||
count++;
|
||||
li.next();
|
||||
prev = current;
|
||||
}
|
||||
assert(count == list.size());
|
||||
}
|
||||
|
||||
void testCreate() {
|
||||
cout << "Test create" << endl;
|
||||
SortedIndexedList list = SortedIndexedList(asc);
|
||||
assert(list.size() == 0);
|
||||
assert(list.isEmpty());
|
||||
|
||||
ListIterator it = list.iterator();
|
||||
assert(!it.valid());
|
||||
it.first();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(!it.valid());
|
||||
assert(list.search(i) == -1);
|
||||
try {
|
||||
assert(list.getElement(i));
|
||||
assert(false);
|
||||
} catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
assert(list.remove(i));
|
||||
assert(false);
|
||||
} catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//generate a vector with values between cMin and cMax so that
|
||||
//1) no value that is >=cMin and <=cMax which is a multiple of s is not included
|
||||
//2) values v, v>=cMin and v<=cMax which are a multiple of m (but not of s) are included c/m + 1 times
|
||||
//3) values >=cMin and <=cMax are in random order
|
||||
vector<int> random(int cMin, int cMax, int s, int m) {
|
||||
vector<int> v;
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
if (c % s != 0) {
|
||||
v.push_back(c);
|
||||
if (c % m == 0) {
|
||||
for (int j = 0; j < c / m; j++) {
|
||||
v.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int n = v.size();
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
int j = i + rand() % (n - i);
|
||||
swap(v[i], v[j]);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//generate a vector containing values >=cMin and <=cMax, each included one time, in random order
|
||||
vector<int> random(int cMin, int cMax) {
|
||||
vector<int> v;
|
||||
for (int c = cMin; c <= cMax; c++) {
|
||||
v.push_back(c);
|
||||
}
|
||||
|
||||
int n = v.size();
|
||||
for (int i = 0; i < n - 1; i++) {
|
||||
int j = i + rand() % (n - i);
|
||||
swap(v[i], v[j]);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
//populate the sorted list with values >=cMin and <=cMax a.i.:
|
||||
//1) no value that is >=cMin and <=cMax which is a multiple of s is not included
|
||||
//2) values v, v>=cMin and v<=cMax which are a multiple of m (but not of s) are included c/m + 1 times
|
||||
//3) values >=cMin and <=cMax are in random order
|
||||
int populate(SortedIndexedList& list, int cMin, int cMax, int s, int m) {
|
||||
vector<int> v = random(cMin, cMax, s, m);
|
||||
int n = v.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
list.add(v[i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
//populate the sorted list with values >=cMin and <=cMax, each included one time, in random order
|
||||
void populate(SortedIndexedList& list, int cMin, int cMax) {
|
||||
vector<int> v = random(cMin, cMax);
|
||||
int n = v.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
list.add(v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void testAddAndSearch(Relation r) {
|
||||
cout << "Test add and search" << endl;
|
||||
SortedIndexedList list = SortedIndexedList(r);
|
||||
int vMin = 10;
|
||||
int vMax = 30;
|
||||
int s = 5;
|
||||
int m = 3;
|
||||
int n = populate(list, vMin, vMax, s, m);
|
||||
assert(!list.isEmpty());
|
||||
assert(list.size() == n);
|
||||
|
||||
//we can't find values outside the interval or on invalid positions
|
||||
int d = 30;
|
||||
for (int i = 1; i <= d; i++) {
|
||||
assert(list.search(vMin - i) == -1);
|
||||
assert(list.search(vMax + i) == -1);
|
||||
try{
|
||||
list.getElement(n-1+i);
|
||||
list.getElement(-d);
|
||||
assert(false);
|
||||
} catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
|
||||
//check the relation order
|
||||
ListIterator it = list.iterator();
|
||||
it.first();
|
||||
assert(it.valid());
|
||||
TComp prev = it.getCurrent();
|
||||
it.next();
|
||||
while (it.valid()) {
|
||||
TComp current = it.getCurrent();
|
||||
assert(r(prev, current));
|
||||
prev = current;
|
||||
it.next();
|
||||
}
|
||||
testIteratorSteps(list, r);
|
||||
|
||||
//check if added values can be found
|
||||
for (int v = vMin; v <= vMax; v++) {
|
||||
int p = list.search(v);
|
||||
//we can't find values which are a multiple of s
|
||||
assert((p != -1) == (v % s != 0));
|
||||
//values which are a multiple of m can be found exactly v/m+1 times
|
||||
if (p != -1 && v%m == 0){
|
||||
for (int i=0; i<=v/m; i++){
|
||||
try{
|
||||
assert(list.remove(p) == v);
|
||||
} catch (exception&) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
assert(list.search(v) == -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testDeleteSearch(Relation r) {
|
||||
cout << "Test delete and search" << endl;
|
||||
SortedIndexedList list = SortedIndexedList(r);
|
||||
int vMin = 0;
|
||||
int vMax = 100;
|
||||
populate(list, vMin, vMax);
|
||||
|
||||
int d = 30;
|
||||
for (int i = 1; i <= d; i++) {
|
||||
try {
|
||||
list.remove(list.search(vMax + i));
|
||||
assert(false);
|
||||
} catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!list.isEmpty());
|
||||
assert(list.size() == vMax - vMin + 1);
|
||||
ListIterator it1 = list.iterator();
|
||||
assert(it1.valid());
|
||||
it1.first();
|
||||
assert(it1.valid());
|
||||
TComp deleted = NULL_TCOMP;
|
||||
testIteratorSteps(list, r);
|
||||
try {
|
||||
deleted = list.remove(list.search(it1.getCurrent()));
|
||||
assert(list.size() == vMax - vMin);
|
||||
it1.first();
|
||||
TComp newFirst = it1.getCurrent();
|
||||
assert(newFirst != deleted);
|
||||
assert(r(deleted, newFirst));
|
||||
it1.first();
|
||||
ListIterator it2 = list.iterator();
|
||||
assert(it2.valid());
|
||||
it2.first();
|
||||
assert(it2.valid());
|
||||
assert(it1.getCurrent() == newFirst && it2.getCurrent() == newFirst);
|
||||
} catch (exception&) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
//delete values in random order while checking the relation order
|
||||
vector<int> vs = random(vMin, vMax);
|
||||
int n = vs.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
testIteratorSteps(list, r);
|
||||
int v = vs[i];
|
||||
try {
|
||||
int it1 = list.search(v);
|
||||
TComp deletedCurrent = list.remove(it1);
|
||||
assert(deletedCurrent != deleted);
|
||||
assert(deletedCurrent == v);
|
||||
assert(list.search(v) == -1);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
ListIterator it2 = list.iterator();
|
||||
it2.first();
|
||||
assert(it2.valid());
|
||||
TComp prev = it2.getCurrent();
|
||||
while (it2.valid()) {
|
||||
TComp current = list.getElement(list.search(it2.getCurrent()));
|
||||
assert(r(prev, current));
|
||||
assert(!r(deletedCurrent, current) || !r(current, deletedCurrent));
|
||||
prev = current;
|
||||
it2.next();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (exception&) {
|
||||
assert(v == deleted);
|
||||
}
|
||||
}
|
||||
|
||||
assert(list.isEmpty());
|
||||
assert(list.size() == 0);
|
||||
}
|
||||
|
||||
void testDeleteSearch() {
|
||||
testDeleteSearch(asc);
|
||||
testDeleteSearch(desc);
|
||||
}
|
||||
|
||||
void testAddAndSearch() {
|
||||
testAddAndSearch(asc);
|
||||
testAddAndSearch(desc);
|
||||
}
|
||||
|
||||
|
||||
void testQuantity(){
|
||||
cout << "Test quantity" << endl;
|
||||
SortedIndexedList list = SortedIndexedList(asc);
|
||||
|
||||
int vMin = 3000;
|
||||
int vMax = 6000;
|
||||
vector<int> values = random(vMin, vMax);
|
||||
int n = values.size();
|
||||
for (int i = 0; i < n; i++){
|
||||
list.add(values[i]);
|
||||
}
|
||||
|
||||
assert(list.size() == vMax - vMin + 1);
|
||||
for (int v = vMin; v <= vMax; v++){
|
||||
assert(list.search(v)>= 0 && list.search(v) < list.size());
|
||||
assert(list.getElement(list.search(v)) == v);
|
||||
}
|
||||
|
||||
ListIterator it = list.iterator();
|
||||
it.first();
|
||||
assert(it.valid());
|
||||
TComp firstElement = it.getCurrent();
|
||||
it.first();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == firstElement);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
it.next();
|
||||
}
|
||||
|
||||
assert(!it.valid());
|
||||
it.first();
|
||||
while (it.valid()){
|
||||
TComp v = it.getCurrent();
|
||||
assert(vMin <= v && v<=vMax);
|
||||
it.next();
|
||||
}
|
||||
assert(!it.valid());
|
||||
|
||||
|
||||
int d = 100;
|
||||
//consider the interval [vMin-d, vMax+d]
|
||||
for (int v = vMin-d; v <= vMax+d; v++){
|
||||
//check that only values from the interval [vMin, vMax] are included in the list
|
||||
assert((list.search(v) != -1) == (vMin <= v && v <= vMax));
|
||||
try{
|
||||
assert(list.remove(list.search(v)));
|
||||
assert(vMin <= v && v <= vMax);
|
||||
} catch (exception&) {
|
||||
assert(vMin > v || v > vMax);
|
||||
}
|
||||
}
|
||||
assert(list.size() == 0);
|
||||
assert(list.isEmpty());
|
||||
}
|
||||
|
||||
void testPrevious(){
|
||||
cout << "Test previous" << endl;
|
||||
SortedIndexedList list = SortedIndexedList(asc);
|
||||
list.add(1);
|
||||
list.add(3);
|
||||
list.add(7);
|
||||
list.add(10);
|
||||
list.add(12);
|
||||
|
||||
ListIterator it = list.iterator();
|
||||
it.last();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == 12);
|
||||
it.previous();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == 10);
|
||||
it.previous();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == 7);
|
||||
it.previous();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == 3);
|
||||
it.previous();
|
||||
assert(it.valid());
|
||||
assert(it.getCurrent() == 1);
|
||||
it.previous();
|
||||
assert(!it.valid());
|
||||
}
|
||||
|
||||
void testAllExtended() {
|
||||
testCreate();
|
||||
testAddAndSearch();
|
||||
testDeleteSearch();
|
||||
testQuantity();
|
||||
testPrevious();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAllExtended();
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "ListIterator.h"
|
||||
#include "SortedIndexedList.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ListIterator::ListIterator(const SortedIndexedList& list) : list(list) {
|
||||
// O(1)
|
||||
this->_current = list._head;
|
||||
}
|
||||
|
||||
void ListIterator::first(){
|
||||
// O(1)
|
||||
this->_current = this->list._head;
|
||||
}
|
||||
|
||||
void ListIterator::next(){
|
||||
// O(1)
|
||||
if(!this->valid())
|
||||
throw exception();
|
||||
this->_current = this->list._next[this->_current];
|
||||
}
|
||||
|
||||
bool ListIterator::valid() const{
|
||||
// O(1)
|
||||
if(this->_current != -1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
TComp ListIterator::getCurrent() const{
|
||||
// O(1)
|
||||
if(this->valid())
|
||||
return this->list._elements[this->_current];
|
||||
return NULL_TCOMP;
|
||||
}
|
||||
|
||||
|
||||
void ListIterator::previous(){
|
||||
// O(1)
|
||||
if(!this->valid())
|
||||
throw exception();
|
||||
this->_current = this->list._prev[this->_current];
|
||||
}
|
||||
|
||||
void ListIterator::last(){
|
||||
// O(1)
|
||||
this->_current = this->list._tail;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "SortedIndexedList.h"
|
||||
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
class ListIterator{
|
||||
friend class SortedIndexedList;
|
||||
private:
|
||||
const SortedIndexedList& list;
|
||||
ListIterator(const SortedIndexedList& list);
|
||||
|
||||
//TODO - Representation
|
||||
int _current;
|
||||
|
||||
public:
|
||||
void first();
|
||||
void last();
|
||||
void next();
|
||||
bool valid() const;
|
||||
TComp getCurrent() const;
|
||||
void previous();
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "ListIterator.h"
|
||||
#include "SortedIndexedList.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool relation1(TComp e1, TComp e2) {
|
||||
if (e1 <= e2) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void testAll(){
|
||||
SortedIndexedList list = SortedIndexedList(relation1);
|
||||
assert(list.size() == 0);
|
||||
assert(list.isEmpty());
|
||||
list.add(1);
|
||||
assert(list.size() == 1);
|
||||
assert(!list.isEmpty());
|
||||
ListIterator iterator = list.iterator();
|
||||
assert(iterator.valid());
|
||||
iterator.first();
|
||||
assert(iterator.getCurrent() == 1);
|
||||
iterator.next();
|
||||
assert(!iterator.valid());
|
||||
iterator.first();
|
||||
assert(iterator.valid());
|
||||
assert(list.search(1) == 0);
|
||||
assert(list.remove(0) == 1);
|
||||
assert(list.size() == 0);
|
||||
assert(list.isEmpty());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAll();
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "ListIterator.h"
|
||||
#include "SortedIndexedList.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include <exception>
|
||||
|
||||
SortedIndexedList::SortedIndexedList(Relation r) {
|
||||
// O(1)
|
||||
this->_relation = r;
|
||||
this->_capacity = 10;
|
||||
this->_length = 0;
|
||||
this->_elements = new TComp[this->_capacity];
|
||||
this->_next = new int[this->_capacity];
|
||||
this->_prev = new int[this->_capacity];
|
||||
for(int i = 0; i < this->_capacity; i++){
|
||||
this->_elements[i] = NULL_TCOMP;
|
||||
this->_next[i] = -1;
|
||||
this->_prev[i] = -1;
|
||||
}
|
||||
this->_head = -1;
|
||||
this->_tail = -1;
|
||||
this->_firstEmpty = 0;
|
||||
}
|
||||
|
||||
int SortedIndexedList::size() const {
|
||||
//O(1)
|
||||
return this->_length;
|
||||
}
|
||||
|
||||
bool SortedIndexedList::isEmpty() const {
|
||||
//O(1)
|
||||
return this->_length == 0;
|
||||
}
|
||||
|
||||
TComp SortedIndexedList::getElement(int i) const{
|
||||
//O(i) - average case | O(i) - worst case | O(i) - best case
|
||||
if(i < 0 || i >= this->_length)
|
||||
throw exception();
|
||||
int current = this->_head;
|
||||
while(i != 0){
|
||||
i--;
|
||||
current = this->_next[current];
|
||||
}
|
||||
return this->_elements[current];
|
||||
}
|
||||
|
||||
TComp SortedIndexedList::remove(int i) {
|
||||
// O(i) - average case | O(i) - worst case | O(i) - best case
|
||||
if(i < 0 || i >= this->_length)
|
||||
throw exception();
|
||||
int current = this->_head;
|
||||
while(i != 0){
|
||||
i--;
|
||||
current = this->_next[current];
|
||||
}
|
||||
TComp removed = this->_elements[current];
|
||||
if(this->_head == current)
|
||||
this->_head = this->_next[current];
|
||||
else
|
||||
this->_next[this->_prev[current]] = this->_next[current];
|
||||
if(this->_tail == current)
|
||||
this->_tail = this->_prev[current];
|
||||
else
|
||||
this->_prev[this->_next[current]] = this->_prev[current];
|
||||
this->_elements[current] = NULL_TCOMP;
|
||||
this->_next[current] = -1;
|
||||
this->_prev[current] = -1;
|
||||
this->_length--;
|
||||
if(this->_firstEmpty > current)
|
||||
this->_firstEmpty = current;
|
||||
return removed;
|
||||
}
|
||||
|
||||
int SortedIndexedList::search(TComp e) const {
|
||||
//O(n) - average case | O(n) - worst case | O(1) - best case
|
||||
int current = this->_head;
|
||||
int i = 0;
|
||||
while(current != -1){
|
||||
if(this->_elements[current] == e)
|
||||
return i;
|
||||
current = this->_next[current];
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SortedIndexedList::add(TComp e) {
|
||||
// O(n) - average case | O(n) - worst case | O(1) - best case
|
||||
if(this->_length == this->_capacity)
|
||||
this->resize();
|
||||
int current = this->_head;
|
||||
int prev = -1;
|
||||
while(current != -1 && this->_relation(this->_elements[current], e)){
|
||||
prev = current;
|
||||
current = this->_next[current];
|
||||
}
|
||||
this->_elements[this->_firstEmpty] = e;
|
||||
this->_next[this->_firstEmpty] = current;
|
||||
this->_prev[this->_firstEmpty] = prev;
|
||||
if(prev == -1)
|
||||
this->_head = this->_firstEmpty;
|
||||
else
|
||||
this->_next[prev] = this->_firstEmpty;
|
||||
if(current == -1)
|
||||
this->_tail = this->_firstEmpty;
|
||||
else
|
||||
this->_prev[current] = this->_firstEmpty;
|
||||
this->_length++;
|
||||
while(this->_firstEmpty < this->_capacity && this->_elements[this->_firstEmpty] != NULL_TCOMP)
|
||||
this->_firstEmpty++;
|
||||
|
||||
}
|
||||
|
||||
ListIterator SortedIndexedList::iterator(){
|
||||
//O(1)
|
||||
return ListIterator(*this);
|
||||
}
|
||||
|
||||
//destructor
|
||||
SortedIndexedList::~SortedIndexedList() {
|
||||
//O(1)
|
||||
delete[] this->_elements;
|
||||
delete[] this->_next;
|
||||
delete[] this->_prev;
|
||||
}
|
||||
|
||||
void SortedIndexedList::resize(){
|
||||
//O(n)
|
||||
this->_capacity *= 2;
|
||||
TComp* newElements = new TComp[this->_capacity];
|
||||
int* newNext = new int[this->_capacity];
|
||||
int* newPrev = new int[this->_capacity];
|
||||
for(int i = 0; i < this->_capacity; i++){
|
||||
newElements[i] = NULL_TCOMP;
|
||||
newNext[i] = -1;
|
||||
newPrev[i] = -1;
|
||||
}
|
||||
for(int i = 0; i < this->_length; i++){
|
||||
newElements[i] = this->_elements[i];
|
||||
newNext[i] = this->_next[i];
|
||||
newPrev[i] = this->_prev[i];
|
||||
}
|
||||
delete[] this->_elements;
|
||||
delete[] this->_next;
|
||||
delete[] this->_prev;
|
||||
this->_elements = newElements;
|
||||
this->_next = newNext;
|
||||
this->_prev = newPrev;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
//DO NOT INCLUDE LISTITERATOR
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
class ListIterator;
|
||||
typedef int TComp;
|
||||
typedef bool (*Relation)(TComp, TComp);
|
||||
#define NULL_TCOMP -11111
|
||||
|
||||
class SortedIndexedList {
|
||||
private:
|
||||
friend class ListIterator;
|
||||
private:
|
||||
//TODO - Representation
|
||||
Relation _relation;
|
||||
int _capacity;
|
||||
int _length;
|
||||
TComp* _elements;
|
||||
int* _next;
|
||||
int* _prev;
|
||||
int _head;
|
||||
int _tail;
|
||||
int _firstEmpty;
|
||||
void resize();
|
||||
|
||||
public:
|
||||
// constructor
|
||||
SortedIndexedList(Relation r);
|
||||
|
||||
// returns the size of the list
|
||||
int size() const;
|
||||
|
||||
//checks if the list is empty
|
||||
bool isEmpty() const;
|
||||
|
||||
// returns an element from a position
|
||||
//throws exception if the position is not valid
|
||||
TComp getElement(int pos) const;
|
||||
|
||||
// adds an element in the sortedList (to the corresponding position)
|
||||
void add(TComp e);
|
||||
|
||||
// removes an element from a given position
|
||||
//returns the removed element
|
||||
//throws an exception if the position is not valid
|
||||
TComp remove(int pos);
|
||||
|
||||
// searches for an element and returns the first position where the element appears or -1 if the element is not in the list
|
||||
int search(TComp e) const;
|
||||
|
||||
// returns an iterator set to the first element of the list or invalid if the list is empty
|
||||
ListIterator iterator();
|
||||
|
||||
//destructor
|
||||
~SortedIndexedList();
|
||||
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "ExtendedTest.h"
|
||||
#include "ShortTest.h"
|
||||
|
||||
#include "Map.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main() {
|
||||
testAll();
|
||||
testAllExtended();
|
||||
|
||||
cout << "That's all!" << endl;
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
#include "ExtendedTest.h"
|
||||
#include "Map.h"
|
||||
#include "MapIterator.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void testIteratorSteps(Map& m) {
|
||||
MapIterator mi = m.iterator();
|
||||
int count = 0;
|
||||
while (mi.valid()) {
|
||||
count++;
|
||||
mi.next();
|
||||
}
|
||||
assert(count == m.size());
|
||||
}
|
||||
|
||||
void testCreate() {
|
||||
cout << "Test create" << endl;
|
||||
Map m;
|
||||
assert(m.size() == 0);
|
||||
assert(m.isEmpty() == true);
|
||||
|
||||
for (int i = -10; i < 10; i++) {
|
||||
assert(m.search(i) == NULL_TVALUE);
|
||||
}
|
||||
for (int i = -10; i < 10; i++) {
|
||||
assert(m.search(i) == NULL_TVALUE);
|
||||
}
|
||||
|
||||
MapIterator it = m.iterator();
|
||||
assert(it.valid() == false);
|
||||
try {
|
||||
it.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it.getCurrent();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void testAdd() {
|
||||
cout << "Test add" << endl;
|
||||
Map m;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(m.add(i, i) == NULL_TVALUE);
|
||||
}
|
||||
assert(m.isEmpty() == false);
|
||||
assert(m.size() == 10);
|
||||
for (int i = -10; i < 0; i++) {
|
||||
assert(m.add(i, i) == NULL_TVALUE);
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assert(m.add(i, i) == i);
|
||||
}
|
||||
for (int i = 10; i < 20; i++) {
|
||||
assert(m.add(i, i) == NULL_TVALUE);
|
||||
}
|
||||
assert(m.isEmpty() == false);
|
||||
assert(m.size() == 30);
|
||||
for (int i = -100; i < 100; i++) {
|
||||
m.add(i, i);
|
||||
}
|
||||
assert(m.isEmpty() == false);
|
||||
assert(m.size() == 200);
|
||||
for (int i = -200; i < 200; i++) {
|
||||
if (i < -100) {
|
||||
assert(m.search(i) == NULL_TVALUE);
|
||||
}
|
||||
else if (i < 0) {
|
||||
assert(m.search(i) == i);
|
||||
}
|
||||
else if (i < 100) {
|
||||
assert(m.search(i) == i);
|
||||
}
|
||||
else {
|
||||
assert(m.search(i) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
for (int i = 10000; i > -10000; i--) {
|
||||
m.add(i, i);
|
||||
}
|
||||
testIteratorSteps(m);
|
||||
assert(m.size() == 20000);
|
||||
}
|
||||
|
||||
|
||||
void testRemove() {
|
||||
cout << "Test remove" << endl;
|
||||
Map m;
|
||||
|
||||
for (int i = -100; i < 100; i++) {
|
||||
assert(m.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
assert(m.size() == 0);
|
||||
for (int i = -100; i < 100; i = i + 2) {
|
||||
assert(m.add(i, i) == NULL_TVALUE);
|
||||
}
|
||||
for (int i = -100; i < 100; i++) {
|
||||
if (i % 2 == 0) {
|
||||
assert(m.remove(i) == i);
|
||||
}
|
||||
else {
|
||||
assert(m.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
assert(m.size() == 0);
|
||||
|
||||
for (int i = -100; i <= 100; i = i + 2) {
|
||||
assert(m.add(i, i) == NULL_TVALUE);
|
||||
}
|
||||
testIteratorSteps(m);
|
||||
for (int i = 100; i > -100; i--) {
|
||||
if (i % 2 == 0) {
|
||||
assert(m.remove(i) == i);
|
||||
}
|
||||
else {
|
||||
assert(m.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
testIteratorSteps(m);
|
||||
}
|
||||
|
||||
assert(m.size() == 1);
|
||||
|
||||
m.remove(-100);
|
||||
assert(m.size() == 0);
|
||||
|
||||
for (int i = -100; i < 100; i++) {
|
||||
assert(m.add(i, 0) == NULL_TVALUE);
|
||||
assert(m.add(i, 1) == 0);
|
||||
assert(m.add(i, 2) == 1);
|
||||
assert(m.add(i, 3) == 2);
|
||||
assert(m.add(i, 4) == 3);
|
||||
}
|
||||
assert(m.size() == 200);
|
||||
for (int i = -200; i < 200; i++) {
|
||||
if (i < -100 || i >= 100) {
|
||||
assert(m.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
else {
|
||||
assert(m.remove(i) == 4);
|
||||
assert(m.remove(i) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
assert(m.size() == 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void testIterator() {
|
||||
cout << "Test iterator" << endl;
|
||||
Map m;
|
||||
MapIterator it = m.iterator();
|
||||
assert(it.valid() == false);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
m.add(33, 33);
|
||||
}
|
||||
MapIterator it2 = m.iterator();
|
||||
assert(it2.valid() == true);
|
||||
TElem el = it2.getCurrent();
|
||||
assert(el.first == 33);
|
||||
assert(el.second == 33);
|
||||
it2.next();
|
||||
assert(it2.valid() == false);
|
||||
try {
|
||||
it2.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it2.getCurrent();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
|
||||
it2.first();
|
||||
assert(it2.valid() == true);
|
||||
|
||||
Map m2;
|
||||
for (int i = -100; i < 100; i++) {
|
||||
assert(m2.add(i, i) == NULL_TVALUE);
|
||||
assert(m2.add(i, i) == i);
|
||||
assert(m2.add(i, i) == i);
|
||||
}
|
||||
MapIterator it3 = m2.iterator();
|
||||
assert(it3.valid() == true);
|
||||
for (int i = 0; i < 200; i++) {
|
||||
it3.next();
|
||||
}
|
||||
assert(it3.valid() == false);
|
||||
it3.first();
|
||||
assert(it3.valid() == true);
|
||||
|
||||
Map m3;
|
||||
for (int i = 0; i < 200; i = i + 4) {
|
||||
m3.add(i, i);
|
||||
}
|
||||
|
||||
MapIterator it4 = m3.iterator();
|
||||
assert(it4.valid() == true);
|
||||
int count = 0;
|
||||
while (it4.valid()) {
|
||||
TElem e = it4.getCurrent();
|
||||
assert(e.first % 4 == 0);
|
||||
it4.next();
|
||||
count++;
|
||||
}
|
||||
assert(count == 50);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void testQuantity() {
|
||||
Map m;
|
||||
cout << "Test quantity" << endl;
|
||||
for (int j = 0; j < 30000; j = j + 1) {
|
||||
assert(m.add(j, j) == NULL_TVALUE);
|
||||
}
|
||||
for (int i = 10; i >= 1; i--) {
|
||||
for (int j = 0; j < 30000; j = j + i) {
|
||||
assert(m.add(j, j) == j);
|
||||
}
|
||||
}
|
||||
assert(m.size() == 30000);
|
||||
MapIterator it = m.iterator();
|
||||
assert(it.valid() == true);
|
||||
for (int i = 0; i < m.size(); i++) {
|
||||
it.next();
|
||||
}
|
||||
it.first();
|
||||
while (it.valid()) {
|
||||
TElem e = it.getCurrent();
|
||||
assert(m.search(e.first) == e.first);
|
||||
it.next();
|
||||
}
|
||||
assert(it.valid() == false);
|
||||
|
||||
for (int j = 30000 - 1; j >= 0; j--) {
|
||||
assert(m.remove(j) == j);
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 40000; j >= -4000; j--) {
|
||||
assert(m.remove(j) == NULL_TVALUE);
|
||||
}
|
||||
}
|
||||
assert(m.size() == 0);
|
||||
}
|
||||
|
||||
void testExtra()
|
||||
{
|
||||
cout << "Test extra" << endl;
|
||||
Map m;
|
||||
assert(m.isEmpty() == true);
|
||||
assert(m.getKeyRange() == -1);
|
||||
assert(m.add(1, 2) == NULL_TVALUE);
|
||||
assert(m.add(1, 3) == 2);
|
||||
assert(m.add(2, 3) == NULL_TVALUE);
|
||||
assert(m.getKeyRange() == 1);
|
||||
assert(m.add(100, 100) == NULL_TVALUE);
|
||||
assert(m.getKeyRange() == 99);
|
||||
}
|
||||
|
||||
void testAllExtended() {
|
||||
testCreate();
|
||||
testAdd();
|
||||
testRemove();
|
||||
testIterator();
|
||||
testQuantity();
|
||||
testExtra();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAllExtended();
|
||||
@@ -0,0 +1,170 @@
|
||||
#include "Map.h"
|
||||
#include "MapIterator.h"
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
|
||||
Map::Map() {
|
||||
//O(1)
|
||||
this->_capacity=INITIAL_CAPACITY;
|
||||
this->_size=0;
|
||||
this->_elements=new TElem[this->_capacity];
|
||||
this->_next=new int[this->_capacity];
|
||||
for(int i=0;i<this->_capacity;i++){
|
||||
this->_elements[i]=NULL_TELEM;
|
||||
this->_next[i]=-1;
|
||||
}
|
||||
this->_nextFree=INITIAL_CAPACITY-1;
|
||||
}
|
||||
|
||||
Map::~Map() {
|
||||
//O(1)
|
||||
delete[] this->_elements;
|
||||
delete[] this->_next;
|
||||
}
|
||||
|
||||
TValue Map::add(TKey c, TValue v){
|
||||
// O(1) - amortized
|
||||
if(this->_size>=this->_capacity*ALPHA)
|
||||
this->_resize();
|
||||
int hash=abs(c % this->_capacity);
|
||||
while(this->_next[hash]!=-1 && this->_elements[hash].first!=c)
|
||||
hash=this->_next[hash];
|
||||
if(this->_elements[hash].first==c){
|
||||
TValue oldValue=this->_elements[hash].second;
|
||||
this->_elements[hash].second=v;
|
||||
return oldValue;
|
||||
}
|
||||
this->_elements[this->_nextFree]=std::make_pair(c,v);
|
||||
this->_next[hash]=this->_nextFree;
|
||||
while(this->_elements[this->_nextFree]!=NULL_TELEM)
|
||||
this->_nextFree--;
|
||||
this->_size++;
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
|
||||
TValue Map::search(TKey c) const{
|
||||
// O(1) - amortized
|
||||
int hash = abs(c % this->_capacity);
|
||||
while (this->_next[hash] != -1 && this->_elements[hash].first != c)
|
||||
hash = this->_next[hash];
|
||||
if (this->_elements[hash].first == c)
|
||||
return this->_elements[hash].second;
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
|
||||
TValue Map::remove(TKey c){
|
||||
//O(1) - amortized
|
||||
int hash = abs(c % this->_capacity);
|
||||
int prev = -1;
|
||||
while (this->_next[hash] != -1 && this->_elements[hash].first != c) {
|
||||
prev = hash;
|
||||
hash = this->_next[hash];
|
||||
}
|
||||
if (this->_elements[hash].first == c) {
|
||||
TValue oldValue = this->_elements[hash].second;
|
||||
if (prev == -1) {
|
||||
if(this->_next[hash]!=-1){
|
||||
int remove = this->_next[hash];
|
||||
this->_elements[hash] = this->_elements[this->_next[hash]];
|
||||
this->_next[hash] = this->_next[this->_next[hash]];
|
||||
this->_next[remove] = -1;
|
||||
this->_elements[remove] = NULL_TELEM;
|
||||
hash = remove;
|
||||
}
|
||||
else
|
||||
this->_elements[hash] = NULL_TELEM;
|
||||
}
|
||||
else {
|
||||
this->_next[prev] = this->_next[hash];
|
||||
this->_elements[hash] = NULL_TELEM;
|
||||
this->_next[hash] = -1;
|
||||
}
|
||||
if(hash>this->_nextFree)
|
||||
this->_nextFree = hash;
|
||||
this->_size--;
|
||||
return oldValue;
|
||||
}
|
||||
return NULL_TVALUE;
|
||||
}
|
||||
|
||||
|
||||
int Map::size() const {
|
||||
//O(1)
|
||||
return this->_size;
|
||||
}
|
||||
|
||||
bool Map::isEmpty() const{
|
||||
//O(1)
|
||||
return (this->_size==0);
|
||||
}
|
||||
|
||||
MapIterator Map::iterator() const {
|
||||
return MapIterator(*this);
|
||||
}
|
||||
|
||||
void Map::_resize() {
|
||||
//O(n)
|
||||
int oldCapacity=this->_capacity;
|
||||
this->_capacity*=2;
|
||||
while(true){
|
||||
bool ok=true;
|
||||
for(int i=2;i<=sqrt(this->_capacity);i++)
|
||||
if(this->_capacity%i==0){
|
||||
ok=false;
|
||||
break;
|
||||
}
|
||||
if(ok)
|
||||
break;
|
||||
this->_capacity++;
|
||||
}
|
||||
TElem* newElements=new TElem[this->_capacity];
|
||||
int* newNext=new int[this->_capacity];
|
||||
for(int i=0;i<this->_capacity;i++){
|
||||
newElements[i]=NULL_TELEM;
|
||||
newNext[i]=-1;
|
||||
}
|
||||
this->_nextFree=this->_capacity-1;
|
||||
for(int i=0;i<oldCapacity;i++){
|
||||
if(this->_elements[i]!=NULL_TELEM){
|
||||
int hash=abs(this->_elements[i].first % this->_capacity);
|
||||
while(newNext[hash]!=-1)
|
||||
hash=this->_next[hash];
|
||||
if(newElements[hash]==NULL_TELEM){
|
||||
newElements[hash]=this->_elements[i];
|
||||
newNext[hash]=-1;
|
||||
}
|
||||
else{
|
||||
newElements[this->_nextFree]=this->_elements[i];
|
||||
newNext[hash]=this->_nextFree;
|
||||
while(newElements[this->_nextFree]!=NULL_TELEM)
|
||||
this->_nextFree--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
delete[] this->_elements;
|
||||
delete[] this->_next;
|
||||
this->_elements=newElements;
|
||||
this->_next=newNext;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int Map::getKeyRange() const{
|
||||
//O(n)
|
||||
MapIterator it = this->iterator();
|
||||
if (!it.valid())
|
||||
return -1;
|
||||
int min = it.getCurrent().first;
|
||||
int max = it.getCurrent().first;
|
||||
while (it.valid()) {
|
||||
if (it.getCurrent().first < min)
|
||||
min = it.getCurrent().first;
|
||||
if (it.getCurrent().first > max)
|
||||
max = it.getCurrent().first;
|
||||
it.next();
|
||||
}
|
||||
return max - min;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
using namespace std;
|
||||
//DO NOT INCLUDE MAPITERATOR
|
||||
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
typedef int TKey;
|
||||
typedef int TValue;
|
||||
typedef std::pair<TKey, TValue> TElem;
|
||||
#define NULL_TVALUE -111111
|
||||
#define NULL_TELEM pair<TKey, TValue>(-111111, -111111)
|
||||
#define ALPHA 0.75
|
||||
#define INITIAL_CAPACITY 2300000
|
||||
class MapIterator;
|
||||
|
||||
|
||||
|
||||
class Map {
|
||||
//DO NOT CHANGE THIS PART
|
||||
friend class MapIterator;
|
||||
|
||||
private:
|
||||
//TODO - Representation
|
||||
TElem* _elements;
|
||||
int* _next;
|
||||
int _size;
|
||||
int _capacity;
|
||||
int _nextFree;
|
||||
void _resize();
|
||||
|
||||
public:
|
||||
|
||||
// implicit constructor
|
||||
Map();
|
||||
|
||||
// adds a pair (key,value) to the map
|
||||
//if the key already exists in the map, then the value associated to the key is replaced by the new value and the old value is returned
|
||||
//if the key does not exist, a new pair is added and the value null is returned
|
||||
TValue add(TKey c, TValue v);
|
||||
|
||||
//searches for the key and returns the value associated with the key if the map contains the key or null: NULL_TVALUE otherwise
|
||||
TValue search(TKey c) const;
|
||||
|
||||
//removes a key from the map and returns the value associated with the key if the key existed ot null: NULL_TVALUE otherwise
|
||||
TValue remove(TKey c);
|
||||
|
||||
//returns the number of pairs (key,value) from the map
|
||||
int size() const;
|
||||
|
||||
//checks whether the map is empty or not
|
||||
bool isEmpty() const;
|
||||
|
||||
//returns an iterator for the map
|
||||
MapIterator iterator() const;
|
||||
|
||||
|
||||
int getKeyRange() const;
|
||||
|
||||
// destructor
|
||||
~Map();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "Map.h"
|
||||
#include "MapIterator.h"
|
||||
#include <exception>
|
||||
using namespace std;
|
||||
|
||||
|
||||
MapIterator::MapIterator(const Map& d) : map(d)
|
||||
{
|
||||
//O(1)
|
||||
this->_current=0;
|
||||
while (this->_current<this->map._capacity && this->map._elements[this->_current]==NULL_TELEM)
|
||||
{
|
||||
this->_current++;
|
||||
}
|
||||
this->_first=this->_current;
|
||||
}
|
||||
|
||||
|
||||
void MapIterator::first() {
|
||||
//O(1)
|
||||
this->_current=this->_first;
|
||||
}
|
||||
|
||||
|
||||
void MapIterator::next() {
|
||||
//O(1)
|
||||
if(this->valid()){
|
||||
this->_current++;
|
||||
while (this->_current<this->map._capacity && this->map._elements[this->_current]==NULL_TELEM)
|
||||
{
|
||||
this->_current++;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw exception();
|
||||
}
|
||||
|
||||
|
||||
TElem MapIterator::getCurrent(){
|
||||
//O(1)
|
||||
if(this->valid())
|
||||
return this->map._elements[this->_current];
|
||||
throw exception();
|
||||
}
|
||||
|
||||
|
||||
bool MapIterator::valid() const {
|
||||
//O(1)
|
||||
if(this->_current<this->map._capacity && this->map._elements[this->_current]!=NULL_TELEM)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "Map.h"
|
||||
class MapIterator
|
||||
{
|
||||
//DO NOT CHANGE THIS PART
|
||||
friend class Map;
|
||||
private:
|
||||
const Map& map;
|
||||
//TODO - Representation
|
||||
int _current;
|
||||
int _first;
|
||||
|
||||
MapIterator(const Map& m);
|
||||
public:
|
||||
void first();
|
||||
void next();
|
||||
TElem getCurrent();
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "ShortTest.h"
|
||||
#include <assert.h>
|
||||
#include "Map.h"
|
||||
#include "MapIterator.h"
|
||||
|
||||
|
||||
void testAll() { //call each function to see if it is implemented
|
||||
Map m;
|
||||
assert(m.isEmpty() == true);
|
||||
assert(m.size() == 0); //add elements
|
||||
assert(m.add(5,5)==NULL_TVALUE);
|
||||
assert(m.add(1,111)==NULL_TVALUE);
|
||||
assert(m.add(10,110)==NULL_TVALUE);
|
||||
assert(m.add(7,7)==NULL_TVALUE);
|
||||
assert(m.add(1,1)==111);
|
||||
assert(m.add(10,10)==110);
|
||||
assert(m.add(-3,-3)==NULL_TVALUE);
|
||||
assert(m.size() == 5);
|
||||
assert(m.search(10) == 10);
|
||||
assert(m.search(16) == NULL_TVALUE);
|
||||
assert(m.remove(1) == 1);
|
||||
assert(m.remove(6) == NULL_TVALUE);
|
||||
assert(m.size() == 4);
|
||||
|
||||
|
||||
TElem e;
|
||||
MapIterator id = m.iterator();
|
||||
id.first();
|
||||
int s1 = 0, s2 = 0;
|
||||
while (id.valid()) {
|
||||
e = id.getCurrent();
|
||||
s1 += e.first;
|
||||
s2 += e.second;
|
||||
id.next();
|
||||
}
|
||||
assert(s1 == 19);
|
||||
assert(s2 == 19);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
void testAll();
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "SortedBag.h"
|
||||
#include "SortedBagIterator.h"
|
||||
#include <iostream>
|
||||
#include "ShortTest.h"
|
||||
#include "ExtendedTest.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
testAll();
|
||||
testAllExtended();
|
||||
|
||||
cout << "Test over" << endl;
|
||||
system("pause");
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
#include "ShortTest.h"
|
||||
#include "SortedBag.h"
|
||||
#include "SortedBagIterator.h"
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool relation2(TComp r1, TComp r2) {
|
||||
return r1 <= r2;
|
||||
}
|
||||
|
||||
bool relation3(TComp r1, TComp r2) {
|
||||
return r1 >= r2;
|
||||
}
|
||||
|
||||
|
||||
void testCreate() {
|
||||
cout << "Test create" << endl;
|
||||
SortedBag sb(relation2);
|
||||
assert(sb.isEmpty() == true);
|
||||
assert(sb.size() == 0);
|
||||
|
||||
for (int i = -10; i < 30; i++) {
|
||||
assert(sb.remove(i) == false);
|
||||
}
|
||||
for (int i = -10; i < 30; i++) {
|
||||
assert(sb.search(i) == false);
|
||||
}
|
||||
for (int i = -10; i < 30; i++) {
|
||||
assert(sb.nrOccurrences(i) == 0);
|
||||
}
|
||||
SortedBagIterator it = sb.iterator();
|
||||
assert(it.valid() == false);
|
||||
try {
|
||||
it.getCurrent();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
|
||||
void testIterator(SortedBag& sb, Relation rel) {
|
||||
SortedBagIterator it = sb.iterator();
|
||||
TComp e1;
|
||||
TComp e2;
|
||||
if (it.valid()) {
|
||||
e1 = it.getCurrent();
|
||||
it.next();
|
||||
}
|
||||
while (it.valid()) {
|
||||
e2 = e1;
|
||||
e1 = it.getCurrent();
|
||||
it.next();
|
||||
assert(sb.search(e1) == true);
|
||||
assert(sb.search(e2) == true);
|
||||
assert(sb.nrOccurrences(e1) > 0);
|
||||
assert(sb.nrOccurrences(e2) > 0);
|
||||
assert(rel(e2, e1));
|
||||
}
|
||||
try {
|
||||
it.getCurrent();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
try {
|
||||
it.next();
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
it.first();
|
||||
assert(it.valid() == true);
|
||||
it.first();
|
||||
int count = 0;
|
||||
while (it.valid()) {
|
||||
count++;
|
||||
it.next();
|
||||
}
|
||||
assert(count == sb.size());
|
||||
}
|
||||
|
||||
void testAdd(Relation r) {
|
||||
cout << "Test add" << endl;
|
||||
SortedBag sb(r);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
|
||||
sb.add(i);
|
||||
}
|
||||
assert(sb.size() == 100);
|
||||
assert(sb.isEmpty() == false);
|
||||
testIterator(sb, r);
|
||||
|
||||
for (int i = 200; i >= -200; i--) {
|
||||
sb.add(i);
|
||||
}
|
||||
assert(sb.size() == 501);
|
||||
testIterator(sb, r);
|
||||
|
||||
for (int i = -300; i < 300; i++) {
|
||||
bool exista = sb.search(i);
|
||||
int nrA = sb.nrOccurrences(i);
|
||||
|
||||
if (i < -200 || i > 200) {
|
||||
assert(exista == false);
|
||||
assert(nrA == 0);
|
||||
}
|
||||
else if (i >= -200 && i < 0) {
|
||||
assert(exista == true);
|
||||
assert(nrA == 1);
|
||||
}
|
||||
else if (i >= 0 && i < 100) {
|
||||
assert(exista == true);
|
||||
assert(nrA == 2);
|
||||
}
|
||||
else if (i >= 100 && i <= 200) {
|
||||
assert(exista == true);
|
||||
assert(nrA == 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
sb.add(0);
|
||||
}
|
||||
assert(sb.nrOccurrences(0) == 102);
|
||||
testIterator(sb, r);
|
||||
|
||||
SortedBag sb2(r);
|
||||
for (int i = 0; i < 300; i = i + 2) {
|
||||
sb2.add(i);
|
||||
sb2.add(2 * i);
|
||||
sb2.add(-2 * i);
|
||||
}
|
||||
assert(sb2.size() == 450);
|
||||
testIterator(sb2, r);
|
||||
}
|
||||
|
||||
void testRemove(Relation r) {
|
||||
cout << "Test remove" << endl;
|
||||
SortedBag sb(r);
|
||||
for (int i = -100; i < 100; i++) {
|
||||
assert(sb.remove(i) == false);
|
||||
assert(sb.search(i) == false);
|
||||
assert(sb.nrOccurrences(i) == 0);
|
||||
}
|
||||
assert(sb.isEmpty() == true);
|
||||
|
||||
for (int i = -100; i < 100; i++) {
|
||||
sb.add(i);
|
||||
}
|
||||
assert(sb.size() == 200);
|
||||
for (int i = -100; i < 100; i = i + 2) {
|
||||
assert(sb.remove(i) == true);
|
||||
}
|
||||
assert(sb.size() == 100);
|
||||
for (int i = -100; i < 100; i++) {
|
||||
if (i % 2 == 0) {
|
||||
assert(sb.nrOccurrences(i) == 0);
|
||||
assert(sb.search(i) == false);
|
||||
assert(sb.remove(i) == false);
|
||||
}
|
||||
else {
|
||||
assert(sb.nrOccurrences(i) == 1);
|
||||
assert(sb.search(i) == true);
|
||||
}
|
||||
sb.add(i);
|
||||
sb.add(i);
|
||||
sb.add(i);
|
||||
}
|
||||
assert(sb.size() == 700);
|
||||
for (int i = -200; i < 200; i++) {
|
||||
if (i < -100 || i >= 100) {
|
||||
assert(sb.search(i) == false);
|
||||
assert(sb.nrOccurrences(i) == 0);
|
||||
assert(sb.remove(i) == false);
|
||||
}
|
||||
else if (i % 2 == 0) {
|
||||
assert(sb.search(i) == true);
|
||||
assert(sb.nrOccurrences(i) == 3);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == false);
|
||||
}
|
||||
else {
|
||||
assert(sb.search(i) == true);
|
||||
assert(sb.nrOccurrences(i) == 4);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == true);
|
||||
assert(sb.remove(i) == false);
|
||||
}
|
||||
}
|
||||
SortedBag sb2(r);
|
||||
for (int i = 300; i >= -500; i--) {
|
||||
sb2.add(i);
|
||||
sb2.add(i * 2);
|
||||
sb2.add(-2 * i);
|
||||
}
|
||||
for (int i = -100; i < 100; i++) {
|
||||
for (int j = 0; j < 100; j++) {
|
||||
sb2.remove(i);
|
||||
}
|
||||
}
|
||||
for (int i = -100; i < 0; i++) {
|
||||
assert(sb2.nrOccurrences(i) == 0);
|
||||
assert(sb2.search(i) == false);
|
||||
}
|
||||
}
|
||||
|
||||
void testQuantity(Relation r) {
|
||||
cout << "Test quantity" << endl;
|
||||
SortedBag sb(r);
|
||||
for (int j = 0; j < 10; j++) {
|
||||
sb.add(0);
|
||||
for (int i = 1; i < 300; i++) {
|
||||
sb.add(i);
|
||||
sb.add(-i);
|
||||
}
|
||||
sb.add(-3000);
|
||||
}
|
||||
int count = 6000;
|
||||
assert(sb.size() == 6000);
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
TComp nr = rand() % 8000 - 4000;
|
||||
if (sb.remove(nr) == true) {
|
||||
count--;
|
||||
}
|
||||
assert(sb.size() == count);
|
||||
}
|
||||
assert(sb.size() == count);
|
||||
}
|
||||
|
||||
void testIterator(Relation rel) {
|
||||
cout << "Test iterator" << endl;
|
||||
SortedBag sb(rel);
|
||||
for (int i = 0; i < 500; i++) {
|
||||
sb.add(i);
|
||||
sb.add(-2 * i);
|
||||
sb.add(2 * i);
|
||||
sb.add(i);
|
||||
sb.add(-2 * i);
|
||||
sb.add(2 * i);
|
||||
}
|
||||
|
||||
assert(sb.size() == 3000);
|
||||
|
||||
SortedBagIterator sbi = sb.iterator();
|
||||
int count = 0;
|
||||
while (sbi.valid()) {
|
||||
count++;
|
||||
sbi.next();
|
||||
}
|
||||
assert(count == sb.size());
|
||||
sbi.first();
|
||||
TElem e = sbi.getCurrent();
|
||||
sbi.next();
|
||||
count = 1;
|
||||
while (sbi.valid()) {
|
||||
TElem ee = sbi.getCurrent();
|
||||
assert(rel(e, ee));
|
||||
TElem ee2 = sbi.getCurrent();
|
||||
assert(ee == ee2);
|
||||
TElem ee3 = sbi.getCurrent();
|
||||
assert(ee == ee3);
|
||||
e = ee;
|
||||
sbi.next();
|
||||
count++;
|
||||
}
|
||||
assert(count == sb.size());
|
||||
}
|
||||
|
||||
void testExtra(){
|
||||
cout << "Test extra" << endl;
|
||||
SortedBag sb(relation2);
|
||||
sb.add(2);
|
||||
sb.add(2);
|
||||
sb.add(2);
|
||||
sb.add(1);
|
||||
sb.add(1);
|
||||
sb.add(1);
|
||||
sb.add(1);
|
||||
sb.add(2);
|
||||
sb.add(5);
|
||||
sb.add(3);
|
||||
sb.add(4);
|
||||
assert(sb.size() == 11);
|
||||
assert(sb.nrOccurrences(1) == 4);
|
||||
assert(sb.nrOccurrences(2) == 4);
|
||||
assert(sb.nrOccurrences(3) == 1);
|
||||
assert(sb.nrOccurrences(4) == 1);
|
||||
assert(sb.nrOccurrences(5) == 1);
|
||||
assert(sb.elementsWithThisFrequency(1) == 3);
|
||||
assert(sb.elementsWithThisFrequency(4) == 2);
|
||||
try {
|
||||
sb.elementsWithThisFrequency(0);
|
||||
assert(false);
|
||||
}
|
||||
catch (exception&) {
|
||||
assert(true);
|
||||
}
|
||||
}
|
||||
|
||||
void testAllExtended() {
|
||||
testCreate();
|
||||
testAdd(relation2);
|
||||
testAdd(relation3);
|
||||
testRemove(relation2);
|
||||
testRemove(relation3);
|
||||
testIterator(relation2);
|
||||
testIterator(relation3);
|
||||
testQuantity(relation2);
|
||||
testQuantity(relation3);
|
||||
testExtra();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAllExtended();
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "ShortTest.h"
|
||||
#include "SortedBag.h"
|
||||
#include "SortedBagIterator.h"
|
||||
#include <assert.h>
|
||||
|
||||
bool relation1(TComp e1, TComp e2) {
|
||||
return e1 <= e2;
|
||||
}
|
||||
|
||||
void testAll() {
|
||||
SortedBag sb(relation1);
|
||||
sb.add(5);
|
||||
sb.add(6);
|
||||
sb.add(0);
|
||||
sb.add(5);
|
||||
sb.add(10);
|
||||
sb.add(8);
|
||||
|
||||
assert(sb.size() == 6);
|
||||
assert(sb.nrOccurrences(5) == 2);
|
||||
|
||||
assert(sb.remove(5) == true);
|
||||
assert(sb.size() == 5);
|
||||
|
||||
assert(sb.search(6) == true);
|
||||
assert(sb.isEmpty() == false);
|
||||
|
||||
SortedBagIterator it = sb.iterator();
|
||||
assert(it.valid() == true);
|
||||
while (it.valid()) {
|
||||
it.getCurrent();
|
||||
it.next();
|
||||
}
|
||||
assert(it.valid() == false);
|
||||
it.first();
|
||||
assert(it.valid() == true);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void testAll();
|
||||
@@ -0,0 +1,239 @@
|
||||
#include "SortedBag.h"
|
||||
#include "SortedBagIterator.h"
|
||||
#include <exception>
|
||||
|
||||
SortedBag::SortedBag(Relation r) {
|
||||
//TODO - Implementation
|
||||
this->relation = r;
|
||||
this->root = nullptr;
|
||||
this->length = 0;
|
||||
}
|
||||
|
||||
void SortedBag::add(TComp e) {
|
||||
//Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
BSTNode* newNode = new BSTNode;
|
||||
newNode->elem = e;
|
||||
newNode->left = nullptr;
|
||||
newNode->right = nullptr;
|
||||
newNode->parent = nullptr;
|
||||
newNode->count = 1;
|
||||
if (this->root == nullptr) {
|
||||
this->root = newNode;
|
||||
this->length++;
|
||||
return;
|
||||
}
|
||||
BSTNode* current = this->root;
|
||||
while (current != nullptr) {
|
||||
if (current->elem == e) {
|
||||
current->count++;
|
||||
this->length++;
|
||||
return;
|
||||
}
|
||||
if (this->relation(e, current->elem)) {
|
||||
if (current->left == nullptr) {
|
||||
current->left = newNode;
|
||||
newNode->parent = current;
|
||||
this->length++;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
current = current->left;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (current->right == nullptr) {
|
||||
current->right = newNode;
|
||||
newNode->parent = current;
|
||||
this->length++;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
current = current->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SortedBag::remove(TComp e) {
|
||||
//Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
BSTNode* current = this->root;
|
||||
while (current != nullptr) {
|
||||
if(current->elem==e){
|
||||
if(current->count>1){
|
||||
current->count--;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
if(current->left==nullptr && current->right==nullptr){
|
||||
if(current->parent==nullptr){
|
||||
this->root=nullptr;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
if(current->parent->left==current){
|
||||
current->parent->left=nullptr;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
current->parent->right=nullptr;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(current->left==nullptr){
|
||||
if(current->parent==nullptr){
|
||||
this->root=current->right;
|
||||
this->root->parent=nullptr;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
if(current->parent->left==current){
|
||||
current->parent->left=current->right;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
current->parent->right=current->right;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(current->right==nullptr){
|
||||
if(current->parent==nullptr){
|
||||
this->root=current->left;
|
||||
this->root->parent=nullptr;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
if(current->parent->left==current){
|
||||
current->parent->left=current->left;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
current->parent->right=current->left;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
BSTNode* current2=current->right;
|
||||
while(current2->left!=nullptr){
|
||||
current2=current2->left;
|
||||
}
|
||||
current->elem=current2->elem;
|
||||
current->count=current2->count;
|
||||
if(current2->parent->left==current2){
|
||||
current2->parent->left=current2->right;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
current2->parent->right=current2->right;
|
||||
this->length--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(this->relation(e,current->elem)){
|
||||
current=current->left;
|
||||
}
|
||||
else{
|
||||
current=current->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool SortedBag::search(TComp elem) const {
|
||||
// Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
BSTNode* current = this->root;
|
||||
while (current != nullptr) {
|
||||
if (current->elem == elem) {
|
||||
return true;
|
||||
}
|
||||
if (this->relation(elem, current->elem)) {
|
||||
current = current->left;
|
||||
}
|
||||
else {
|
||||
current = current->right;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int SortedBag::nrOccurrences(TComp elem) const {
|
||||
// Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
BSTNode* current = this->root;
|
||||
while (current != nullptr) {
|
||||
if (current->elem == elem) {
|
||||
return current->count;
|
||||
}
|
||||
if (this->relation(elem, current->elem)) {
|
||||
current = current->left;
|
||||
}
|
||||
else {
|
||||
current = current->right;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SortedBag::size() const {
|
||||
//O(1)
|
||||
return this->length;
|
||||
}
|
||||
|
||||
|
||||
bool SortedBag::isEmpty() const {
|
||||
//O(1)
|
||||
return (this->length == 0);
|
||||
}
|
||||
|
||||
|
||||
SortedBagIterator SortedBag::iterator() const {
|
||||
return SortedBagIterator(*this);
|
||||
}
|
||||
|
||||
|
||||
SortedBag::~SortedBag() {
|
||||
//O(n)
|
||||
delete this->root;
|
||||
}
|
||||
|
||||
int SortedBag::elementsWithThisFrequency(int frequency) const {
|
||||
// O(n)
|
||||
if(frequency<=0){
|
||||
throw std::exception();
|
||||
}
|
||||
return reccuriveCount(this->root,frequency);
|
||||
}
|
||||
|
||||
int SortedBag::reccuriveCount(BSTNode* node, int frequency) const {
|
||||
if(node==nullptr){
|
||||
return 0;
|
||||
}
|
||||
return reccuriveCount(node->left,frequency)+reccuriveCount(node->right, frequency) + (this->nrOccurrences(node->elem)==frequency);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
//DO NOT INCLUDE SORTEDBAGITERATOR
|
||||
|
||||
//DO NOT CHANGE THIS PART
|
||||
typedef int TComp;
|
||||
typedef TComp TElem;
|
||||
typedef bool(*Relation)(TComp, TComp);
|
||||
#define NULL_TCOMP -11111;
|
||||
|
||||
class BSTNode {
|
||||
public:
|
||||
TComp elem;
|
||||
BSTNode* left;
|
||||
BSTNode* right;
|
||||
BSTNode* parent;
|
||||
~BSTNode() {
|
||||
delete left;
|
||||
delete right;
|
||||
}
|
||||
int count;
|
||||
};
|
||||
|
||||
class SortedBagIterator;
|
||||
|
||||
class SortedBag {
|
||||
friend class SortedBagIterator;
|
||||
|
||||
private:
|
||||
//TODO - Representation
|
||||
BSTNode* root;
|
||||
Relation relation;
|
||||
int length;
|
||||
int reccuriveCount(BSTNode* node, int frequency) const;
|
||||
|
||||
public:
|
||||
//constructor
|
||||
SortedBag(Relation r);
|
||||
|
||||
//adds an element to the sorted bag
|
||||
void add(TComp e);
|
||||
|
||||
//removes one occurence of an element from a sorted bag
|
||||
//returns true if an element was removed, false otherwise (if e was not part of the sorted bag)
|
||||
bool remove(TComp e);
|
||||
|
||||
//checks if an element appearch is the sorted bag
|
||||
bool search(TComp e) const;
|
||||
|
||||
//returns the number of occurrences for an element in the sorted bag
|
||||
int nrOccurrences(TComp e) const;
|
||||
|
||||
//returns the number of elements from the sorted bag
|
||||
int size() const;
|
||||
|
||||
//returns an iterator for this sorted bag
|
||||
SortedBagIterator iterator() const;
|
||||
|
||||
//checks if the sorted bag is empty
|
||||
bool isEmpty() const;
|
||||
|
||||
//destructor
|
||||
~SortedBag();
|
||||
|
||||
int elementsWithThisFrequency(int frequency) const;
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "SortedBagIterator.h"
|
||||
#include "SortedBag.h"
|
||||
#include <exception>
|
||||
|
||||
using namespace std;
|
||||
|
||||
SortedBagIterator::SortedBagIterator(const SortedBag& b) : bag(b) {
|
||||
// Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
this->first();
|
||||
}
|
||||
|
||||
TComp SortedBagIterator::getCurrent() {
|
||||
//O(1)
|
||||
if(this->valid())
|
||||
return this->current->elem;
|
||||
else
|
||||
throw exception();
|
||||
}
|
||||
|
||||
bool SortedBagIterator::valid() {
|
||||
//O(1)
|
||||
if(this->current == nullptr)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SortedBagIterator::next() {
|
||||
// Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
if(this->valid())
|
||||
{
|
||||
if(this->currentCount > 1)
|
||||
this->currentCount--;
|
||||
else
|
||||
{
|
||||
if(this->current->right != nullptr)
|
||||
{
|
||||
this->current = this->current->right;
|
||||
while(this->current->left != nullptr)
|
||||
this->current = this->current->left;
|
||||
this->currentCount = this->current->count;
|
||||
}
|
||||
else
|
||||
{
|
||||
BSTNode* currentParent = this->current->parent;
|
||||
while(currentParent != nullptr && currentParent->right == this->current)
|
||||
{
|
||||
this->current = currentParent;
|
||||
currentParent = currentParent->parent;
|
||||
}
|
||||
this->current = currentParent;
|
||||
if(this->current != nullptr)
|
||||
this->currentCount = this->current->count;
|
||||
else
|
||||
this->currentCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw exception();
|
||||
}
|
||||
|
||||
void SortedBagIterator::first() {
|
||||
// Best case: O(1) Worst case: O(n) Average case: O(log n)
|
||||
this->current = this->bag.root;
|
||||
if(this->current != nullptr){
|
||||
while(this->current->left != nullptr)
|
||||
this->current = this->current->left;
|
||||
this->currentCount = this->current->count;
|
||||
}
|
||||
else{
|
||||
this->currentCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "SortedBag.h"
|
||||
|
||||
class SortedBag;
|
||||
|
||||
class SortedBagIterator
|
||||
{
|
||||
friend class SortedBag;
|
||||
|
||||
private:
|
||||
const SortedBag& bag;
|
||||
SortedBagIterator(const SortedBag& b);
|
||||
|
||||
//TODO - Representation
|
||||
BSTNode* current;
|
||||
int currentCount;
|
||||
|
||||
public:
|
||||
TComp getCurrent();
|
||||
bool valid();
|
||||
void next();
|
||||
void first();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
class Bag:
|
||||
def __init__(self):
|
||||
self.__elements = []
|
||||
def add(self, e):
|
||||
self.__elements.append(e)
|
||||
def remove(self, e):
|
||||
if e in self.__elements:
|
||||
self.__elements.remove(e)
|
||||
return True
|
||||
return False
|
||||
def search(self, e):
|
||||
return e in self.__elements
|
||||
def size(self):
|
||||
return len(self.__elements)
|
||||
def nrOccurrences(self, e):
|
||||
return self.__elements.count(e)
|
||||
def destroy(self):
|
||||
del(self)
|
||||
def iterator(self):
|
||||
return BagIterator(self.__elements)
|
||||
|
||||
|
||||
class BagIterator:
|
||||
def __init__(self, elements):
|
||||
self.__elements = elements
|
||||
self.__current = 0
|
||||
def first(self):
|
||||
self.__current = 0
|
||||
def valid(self):
|
||||
return self.__current < len(self.__elements)
|
||||
def next(self):
|
||||
if self.valid():
|
||||
self.__current += 1
|
||||
def getCurrent(self):
|
||||
if self.valid():
|
||||
return self.__elements[self.__current]
|
||||
else:
|
||||
raise ValueError("Invalid iterator position.")
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
from Bag import Bag, BagIterator
|
||||
|
||||
def createIntBag():
|
||||
intBag=Bag()
|
||||
intBag.add(6)
|
||||
intBag.add(11)
|
||||
intBag.add(77)
|
||||
intBag.add(7)
|
||||
intBag.add(4)
|
||||
intBag.add(6)
|
||||
intBag.add(77)
|
||||
intBag.add(6)
|
||||
return intBag
|
||||
|
||||
def createStringBag():
|
||||
stringBag=Bag()
|
||||
stringBag.add("data")
|
||||
stringBag.add("structures")
|
||||
stringBag.add("and")
|
||||
stringBag.add("algorithms")
|
||||
stringBag.add("data")
|
||||
stringBag.add("data")
|
||||
stringBag.add("algorithms")
|
||||
return stringBag
|
||||
|
||||
def printBag(bag):
|
||||
it = bag.iterator()
|
||||
while it.valid():
|
||||
print(it.getCurrent())
|
||||
it.next()
|
||||
print("Over. Let's start again.")
|
||||
it.first()
|
||||
while it.valid():
|
||||
print(it.getCurrent())
|
||||
it.next()
|
||||
|
||||
def main():
|
||||
b1 = createIntBag()
|
||||
printBag(b1)
|
||||
print("No occurrences of 77: ", b1.nrOccurrences(77))
|
||||
b2 = createStringBag()
|
||||
printBag(b2)
|
||||
print("No occurrences of 'data': ", b2.nrOccurrences("data"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user