Assignment
As we all know Java is a pure obejct oriented programming language and it also provide polymorphism.
In JDK(1.7) architecture, java has its standar container classes. We can have a snapshot with a class diagram to show the relationship between containers.
Note that: 1. A straight line with a circle show that the class is an interface. 2. A straight line with a hollow arrow indicates generalization relationship or in order word, inheritance. 3. A straight line with an unfilled diamon indicates composition relations. 4. Some detials that are irrelevant have been admitted.
Collection is a basic interface. It’s the root of the collection hierarchy. A collection represents a group of objects known as its elements.TheCollection interface is the least common denominator that all collections implement and is used to pass collections around and to manipulate them when maximum generality is desired. Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn’t provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such asSet and List.
Set is a collection which dose not have order and it can not have duplicate elements.
Sorted Set is a set that is sorted.
These two classed are implemented with RB-Tree. If you are insterested in it, you can implement it.
List is collection that carries order, and it’s also a abstract class.
Arraylist is an implantation for list using dynamic extending array.
Vector is thread-safe Arraylist.
Linked list is an implantation for list using nodes which are store in the memory discretely.
* Now you job is to implement the classes in java using c++.*
解答:
//LinkedList.hpp
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include "List.hpp"
#include <iostream>
class LinkedList : virtual public List {
public:
typedef struct node {
E data;
struct node* next;
struct node* prev;
node(E data, struct node* next = NULL, struct node* prev = NULL)
: data(data), next(next), prev(prev) {}
} node;
LinkedList();
~LinkedList();
virtual void add(E e);
virtual void clear(void);
virtual bool contain(E e);
virtual bool isEmpty(void);
virtual void remove(E e);
virtual E& operator[](int index);
virtual E& get(int index);
virtual int indexOf(E element);
virtual void sort(void);
virtual int size(void);
private:
node* head;
node* tail;
int _size;
};
#endif
//LinkedList.cpp
#include "LinkedList.hpp"
LinkedList::LinkedList() {
head = tail = NULL;
_size = 0;
}
LinkedList::~LinkedList() {clear();}
void LinkedList::add(E e) {
if (head == NULL) {
head = new node(e);
tail = head;
_size++;
} else {
node *temp = new node(e);
temp->prev = tail;
tail->next = temp;
tail = temp;
_size++;
}
}
void LinkedList::clear(void) {
node *current = head, *temp;
while (_size--) {
temp = current->next;
delete current;
current = temp;
}
}
bool LinkedList::contain(E e) {
node* temp = this->head;
while (temp != NULL) {
if (temp->data == e) {
return true;
}
temp = temp->next;
}
return false;
}
bool LinkedList::isEmpty(void) {return _size == 0 ? true : false;}
void LinkedList::remove(E e) {
node *temp = head, *t;
while (temp != NULL) {
if (temp->data == e) {
if (temp == head) {
head = temp->next;
if (head != NULL) head->prev = NULL;
if (_size == 1) tail = NULL;
delete temp;
temp = head;
} else if (temp == tail) {
tail = temp->prev;
if (tail != NULL) tail->next = NULL;
if (_size == 1) head = NULL;
delete temp;
temp = NULL;
} else {
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
t = temp, temp = temp->next;
delete t;
}
_size--;
} else {temp = temp->next;}
}
}
E& LinkedList::operator[](int index) {
return get(index);
}
E& LinkedList::get(int index) {
node *temp = head;
for (int i = 0; i < index; i++) {
temp = temp->next;
}
return temp->data;
}
int LinkedList::indexOf(E element) {
node *temp = head;
for (int i = 0; i < _size; ++i) {
if (temp->data == element)
return i;
temp = temp->next;
}
return -1;
}
void LinkedList::sort(void) {
int arr[10000], i, j, temp;
node *tn = head;
for (i = 0; i < _size; ++i) {
arr[i] = tn->data;
tn = tn->next;
}
for (i = 0; i < _size; ++i)
for (j = i; j < _size; ++j)
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
tn = head;
for (i = 0; i < _size; ++i) {
tn->data = arr[i];
tn = tn->next;
}
}
int LinkedList::size(void) {return _size;}
//ArrayList.hpp:
#ifndef ARRAYLIST_H_
#define ARRAYLIST_H_
#include "List.hpp"
class ArrayList : public List {
public:
ArrayList();
~ArrayList();
virtual void add(E e);
virtual void clear(void);
virtual bool contain(E e);
virtual bool isEmpty(void);
virtual void remove(E e);
virtual E& operator[](int index);
virtual E& get(int index);
virtual int indexOf(E element);
virtual void sort(void);
virtual int size(void);
private:
E* storage;
int _size;
int _maxsize;
static const int extend_factor = 2;
void extend(void);
};
#endif
//ArrayList.cpp
#include "ArrayList.hpp"
ArrayList::ArrayList() {
_size = 0;
_maxsize = 10000;
storage = new int[_maxsize];
}
ArrayList::~ArrayList() {clear();}
void ArrayList::add(E e) {storage[_size++] = e;}
void ArrayList::clear(void) {delete[] storage;}
bool ArrayList::contain(E e) {
for (int i = 0; i < _size; ++i) {
if (storage[i] == e)
return true;
}
return false;
}
bool ArrayList::isEmpty(void) {return (_size == 0) ? true : false;}
void ArrayList::remove(E e) {
int N = _size;
for (int i = 0; i < N; ++i) {
if (storage[i] == e) {
for (int j = i; j < N - 1; ++j)
storage[j] = storage[j + 1];
i--;
_size--;
}
}
}
E& ArrayList::operator[](int index) {return storage[index];}
E& ArrayList::get(int index) {return storage[index];}
int ArrayList::indexOf(E element) {
for (int i = 0; i < _size; ++i)
if (storage[i] == element)
return i;
return -1;
}
void swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void quicksort(int arr[], int left, int right) {
int i, j;
if (left < right) {
i = left;
j = right + 1;
while (1) {
do {
i++;
} while (!(arr[i] >= arr[left] || i == right));
do {
j--;
} while (!(arr[j] <= arr[left] || j == left));
if (i < j)
swap(&arr[i], &arr[j]);
else
break;
}
swap(&arr[left], &arr[j]);
quicksort(arr, left, j - 1);
quicksort(arr, i, right);
}
}
void ArrayList::sort(void) {quicksort(storage, 0, _size - 1);}
int ArrayList::size(void) {return _size;}
void ArrayList::extend(void) {}
//Collection_hpp:
#ifndef Collection_hpp
#define Collection_hpp
typedef int E;
class Collection {
public:
virtual ~Collection() {}
virtual void add(E ele) = 0;
virtual void clear() = 0;
virtual bool contain(E e) = 0;
virtual bool isEmpty() = 0;
virtual void remove(E e) = 0;
virtual int size() = 0;
};
#endif
//List_hpp:
#ifndef List_hpp
#define List_hpp
#include "Collection.hpp"
class List: virtual public Collection {
public:
virtual ~List() {}
virtual E& operator[](int index) = 0;
virtual E& get(int index) = 0;
virtual int indexOf(E element) = 0;
virtual void sort() = 0;
};
#endif
#include <iostream>
#include <cstdlib>
#include "Collection.hpp"
#include "List.hpp"
#include "LinkedList.hpp"
#include "ArrayList.hpp"
#include <exception>
using std::cin;
using std::cout;
using std::endl;
using std::exception;
class AlgorithmnForbidden : public exception {
virtual const char *what() const throw() {
return "Please do not use std::sort or std::list or std::vector .....";
}
};
class TEST {
private:
int *testData;
int data_size;
public:
TEST() {
#if defined(_GLIBCXX_ALGORITHM) || defined(_GLIBCXX_LIST) || \
defined(_GLIBCXX_VECTOR)
//throw AlgorithmnForbidden();
cout << "please do not use algorithm" << endl;
#endif
cin >> data_size;
cout << "test data size:" << data_size << endl;
testData = new int[data_size];
for (int i = 0; i < data_size; i++) {
cin >> testData[i];
}
}
~TEST() { delete[] testData; }
void test_List(Collection *c) {
cout << (c->isEmpty() ? "true" : "false") << endl;
int n = data_size;
for (int i = 0; i < n; i++) {
c->add(testData[i]);
}
reinterpret_cast<List *>(c)->sort();
for (int i = 0; i < n; i++) {
cout << (*reinterpret_cast<List *>(c))[i] << " ";
}
cout << endl;
// not empty
cout << (c->isEmpty() ? "true" : "false") << endl;
for (int i = 0; i < n / 2; i++) {
cout << "(" << (c->contain(i) ? "true" : "false");
cout << ","
<< (reinterpret_cast<List *>(c)->indexOf(i) != -1 ? "true" : "false")
<< ") ";
c->remove(i);
}
cout << endl;
for (int i = 0; i < c->size(); i++) {
cout << (*reinterpret_cast<List *>(c))[i] << " ";
}
cout << endl;
}
void test_ArrayList() {
Collection *c = new ArrayList();
test_List(c);
delete c;
}
void test_LinkedList() {
Collection *c = new LinkedList();
test_List(c);
delete c;
}
void runAllTests() {
cout << "Testing ArrayList:" << endl;
test_ArrayList();
cout << endl;
cout << "Testing LinkedList:" << endl;
test_LinkedList();
}
};
int main() {
TEST t;
t.runAllTests();
return 0;
}
关于这道Collection with Inheritance学到的知识点是:
这道题是继承类的,其中有两个抽象类:Collection和List,List继承了前者
放上代码:
#ifndef Collection_hpp
#define Collection_hpp
class Collection {
protected:
typedef int E;
public:
virtual ~Collection() {}
// 并且加入空函数体, 因为对于析构函数来说
// 是不能定义为纯虚函数的
virtual void add(E e) = 0;
virtual void clear(void) = 0;
virtual bool contain(E e) = 0;
virtual bool isEmpty(void) = 0;
virtual void remove(E e) = 0;
virtual void sort(void) = 0;
virtual int size(void) = 0;
};
#endif // !Collection_hpp
#ifndef LIST_HPP
#define LIST_HPP
#include "Collection.hpp"
class List :public Collection{
public:
virtual ~List() {}
// 与Collection类似, 声明为virtual
virtual E& operator[](int index) = 0;
virtual E& get(int index) = 0;
virtual int indexOf(int element) = 0;
};
一、在Collection 的构造过程中,一定要注意析构函数不能省略,并且声明为virtual,如果不将析构函数写成virtual,或者省略,最后析构函数就不会具有多态的特性,导致ArrayList 或者其他的一些类的析构函数不会被调用导致内存泄漏。
二、个人认为,因为在List中父类的虚函数没有变化,所以在List里是可以省略掉声明的。不过,在某个继承下去的子类中,一定要对虚函数加以定义。