Correct!
False!
규태
- 규태는 C++ 를 좋아한다. 그런데 잘한다
- C++ tempalate 구현을 했다
구현
//GList.h
#ifndef __LinkedList__GList__
#define __LinkedList__GList__
#include <iostream>
#define USING_NS_GL using namespace glist
using namespace std;
namespace glist {
template <class T> class GList;
// template <class T> class GStack;
// template <class T> class GQueue;
// GElement
template <class T>
class GElement {
public:
GElement(const T& value): next(NULL), data(value) {}
GElement(const GElement<T> &elem) {
next = elem.next;
data = elem.data;
}
~GElement() {};
GElement& operator=(const GElement<T> &elem) {
next = elem.next;
data = elem.data;
return *this;
}
public:
template <class TP> friend class GList;
// template <class TP> friend class GStack;
// template <class TP> friend class GQueue;
private:
GElement *next;
T data;
};
// GList
template <class T>
class GList {
public:
GList() : head(NULL), rear(NULL), elem_cnt(0) {}
~GList() {}
bool isEmpty() const { return elem_cnt == 0; }
unsigned int getLength() const { return elem_cnt; }
void insertElementInFront(const T& value);
void insertElementInEnd(const T& value);
bool insertElementAtIndex(const T& value, unsigned int index);
bool deleteElementInFront();
bool deleteElementInEnd();
bool deleteElementAtIndex(unsigned int index);
void deleteAllElements();
const T& getElementInFront() const;// { return head->data; }
const T& getElementInEnd() const;// { return rear->data; }
const T& getElementAtIndex(unsigned int index) const;
T& operator[](unsigned int index) const;
private:
GElement<T> *head;
GElement<T> *rear;
int elem_cnt;
};
class OutOfRangeException {
public:
OutOfRangeException (const string& what_arg) { msg = string(what_arg); }
string& what() { return msg; }
private:
string msg;
};
// // GStack
// template <class T>
// class GStack {
//
// };
//
// // GQueue
// template <class T>
// class GQueue {
//
// };
}
// Implement of methods
USING_NS_GL;
template <class T>
void GList<T>::insertElementInFront(const T& value) {
GElement<T> *elem = new GElement<T>(value);
if (isEmpty()) {
head = elem;
rear = elem;
}
else {
elem->next = head;
head = elem;
}
elem_cnt++;
}
template <class T>
void GList<T>::insertElementInEnd(const T& value) {
GElement<T> *elem = new GElement<T>(value);
if (isEmpty()) {
head = elem;
rear = elem;
}
else {
rear->next = elem;
rear = elem;
}
elem_cnt++;
}
template <class T>
bool GList<T>::insertElementAtIndex(const T& value, unsigned int index) {
if ((int)index < 0 || (int)index > elem_cnt)
return false;
if (index == 0) {
insertElementInFront(value);
}
else if (index == elem_cnt) {
insertElementInEnd(value);
}
else {
GElement<T> *p = head;
for (int i = 0; i < index - 1; i++) {
p = p->next;
}
GElement<T> *elem = new GElement<T>(value);
elem->next = p->next;
p->next = elem;
elem_cnt++;
}
return true;
}
template <class T>
bool GList<T>::deleteElementInFront() {
if (isEmpty())
return false;
GElement<T> *p = head;
head = head->next;
delete p;
elem_cnt--;
if (isEmpty())
head = rear = NULL;
return true;
}
template <class T>
bool GList<T>::deleteElementInEnd() {
if (isEmpty())
return false;
GElement<T> *target = head;
while (target->next != rear)
target = target->next;
rear = target; // *target(pointer): previous node of target
target = target->next;
delete target;
rear->next = NULL;
elem_cnt--;
if (isEmpty())
head = rear = NULL;
return true;
}
template <class T>
bool GList<T>::deleteElementAtIndex(unsigned int index) {
if (isEmpty())
return false;
if ((int)index < 0 || (int)index > elem_cnt-1)
return false;
if (index == 0) {
deleteElementInFront();
}
else if (index == elem_cnt-1) {
deleteElementInEnd();
}
else {
GElement<T> *target = head;
GElement<T> *prev = NULL;
for (int i = 0; i < index; i++) {
prev = target;
target = target->next;
}
prev->next = target->next;
delete target;
elem_cnt--;
}
return true;
}
template <class T>
void GList<T>::deleteAllElements() {
GElement<T> *p = head;
while (p != NULL) {
GElement<T> *p2 = p;
p = p->next;
delete p2;
elem_cnt--;
}
head = rear = NULL;
}
template <class T>
const T& GList<T>::getElementInFront() const {
if (head == NULL) {
throw OutOfRangeException("(GList)Out of range: getElementInFront");
}
return head->data;
}
template <class T>
const T& GList<T>::getElementInEnd() const {
if (rear == NULL) {
throw OutOfRangeException("(GList)Out of range: getElementInEnd");
}
return rear->data;
}
template <class T>
const T& GList<T>::getElementAtIndex(unsigned int index) const {
if ((int)index < 0 || (int)index > elem_cnt-1) {
throw OutOfRangeException("(GList)Out of range: getElementAtIndex");
}
return (*this)[index];
}
template <class T>
T& GList<T>::operator[](unsigned int index) const {
if ((int)index < 0 || (int)index > elem_cnt-1) {
throw OutOfRangeException("(GList)Out of range: operator[]");
}
GElement<T> *target = head;
for (int i = 0; i < index; i++) {
target = target->next;
}
return target->data;
}
#endif /* defined(__LinkedList__GList__) */
// Glist.cpp
#ifndef __LinkedList__GList__
#define __LinkedList__GList__
#include <iostream>
#define USING_NS_GL using namespace glist
using namespace std;
namespace glist {
template <class T> class GList;
// template <class T> class GStack;
// template <class T> class GQueue;
// GElement
template <class T>
class GElement {
public:
GElement(const T& value): next(NULL), data(value) {}
GElement(const GElement<T> &elem) {
next = elem.next;
data = elem.data;
}
~GElement() {};
GElement& operator=(const GElement<T> &elem) {
next = elem.next;
data = elem.data;
return *this;
}
public:
template <class TP> friend class GList;
// template <class TP> friend class GStack;
// template <class TP> friend class GQueue;
private:
GElement *next;
T data;
};
// GList
template <class T>
class GList {
public:
GList() : head(NULL), rear(NULL), elem_cnt(0) {}
~GList() {}
bool isEmpty() const { return elem_cnt == 0; }
unsigned int getLength() const { return elem_cnt; }
void insertElementInFront(const T& value);
void insertElementInEnd(const T& value);
bool insertElementAtIndex(const T& value, unsigned int index);
bool deleteElementInFront();
bool deleteElementInEnd();
bool deleteElementAtIndex(unsigned int index);
void deleteAllElements();
const T& getElementInFront() const;// { return head->data; }
const T& getElementInEnd() const;// { return rear->data; }
const T& getElementAtIndex(unsigned int index) const;
T& operator[](unsigned int index) const;
private:
GElement<T> *head;
GElement<T> *rear;
int elem_cnt;
};
class OutOfRangeException {
public:
OutOfRangeException (const string& what_arg) { msg = string(what_arg); }
string& what() { return msg; }
private:
string msg;
};
// // GStack
// template <class T>
// class GStack {
//
// };
//
// // GQueue
// template <class T>
// class GQueue {
//
// };
}
// Implement of methods
USING_NS_GL;
template <class T>
void GList<T>::insertElementInFront(const T& value) {
GElement<T> *elem = new GElement<T>(value);
if (isEmpty()) {
head = elem;
rear = elem;
}
else {
elem->next = head;
head = elem;
}
elem_cnt++;
}
template <class T>
void GList<T>::insertElementInEnd(const T& value) {
GElement<T> *elem = new GElement<T>(value);
if (isEmpty()) {
head = elem;
rear = elem;
}
else {
rear->next = elem;
rear = elem;
}
elem_cnt++;
}
template <class T>
bool GList<T>::insertElementAtIndex(const T& value, unsigned int index) {
if ((int)index < 0 || (int)index > elem_cnt)
return false;
if (index == 0) {
insertElementInFront(value);
}
else if (index == elem_cnt) {
insertElementInEnd(value);
}
else {
GElement<T> *p = head;
for (int i = 0; i < index - 1; i++) {
p = p->next;
}
GElement<T> *elem = new GElement<T>(value);
elem->next = p->next;
p->next = elem;
elem_cnt++;
}
return true;
}
template <class T>
bool GList<T>::deleteElementInFront() {
if (isEmpty())
return false;
GElement<T> *p = head;
head = head->next;
delete p;
elem_cnt--;
if (isEmpty())
head = rear = NULL;
return true;
}
template <class T>
bool GList<T>::deleteElementInEnd() {
if (isEmpty())
return false;
GElement<T> *target = head;
while (target->next != rear)
target = target->next;
rear = target; // *target(pointer): previous node of target
target = target->next;
delete target;
rear->next = NULL;
elem_cnt--;
if (isEmpty())
head = rear = NULL;
return true;
}
template <class T>
bool GList<T>::deleteElementAtIndex(unsigned int index) {
if (isEmpty())
return false;
if ((int)index < 0 || (int)index > elem_cnt-1)
return false;
if (index == 0) {
deleteElementInFront();
}
else if (index == elem_cnt-1) {
deleteElementInEnd();
}
else {
GElement<T> *target = head;
GElement<T> *prev = NULL;
for (int i = 0; i < index; i++) {
prev = target;
target = target->next;
}
prev->next = target->next;
delete target;
elem_cnt--;
}
return true;
}
template <class T>
void GList<T>::deleteAllElements() {
GElement<T> *p = head;
while (p != NULL) {
GElement<T> *p2 = p;
p = p->next;
delete p2;
elem_cnt--;
}
head = rear = NULL;
}
template <class T>
const T& GList<T>::getElementInFront() const {
if (head == NULL) {
throw OutOfRangeException("(GList)Out of range: getElementInFront");
}
return head->data;
}
template <class T>
const T& GList<T>::getElementInEnd() const {
if (rear == NULL) {
throw OutOfRangeException("(GList)Out of range: getElementInEnd");
}
return rear->data;
}
template <class T>
const T& GList<T>::getElementAtIndex(unsigned int index) const {
if ((int)index < 0 || (int)index > elem_cnt-1) {
throw OutOfRangeException("(GList)Out of range: getElementAtIndex");
}
return (*this)[index];
}
template <class T>
T& GList<T>::operator[](unsigned int index) const {
if ((int)index < 0 || (int)index > elem_cnt-1) {
throw OutOfRangeException("(GList)Out of range: operator[]");
}
GElement<T> *target = head;
for (int i = 0; i < index; i++) {
target = target->next;
}
return target->data;
}
#endif /* defined(__LinkedList__GList__) */
// main.cpp
#include <iostream>
#include <string>
#include "GList.h"
using namespace std;
USING_NS_GL;
class AClass;
GList<AClass> *g_list = NULL;
class AClass {
public:
AClass(string val) : value(val) {}
string getValue() { return value; }
void setValue(string val) { value = val; }
private:
string value;
};
void Insert();
void Delete();
void Get();
void Modify();
void PrintStrings();
void PrintLengthOfList();
int main(int argc, const char * argv[]) {
g_list = new GList<AClass>();
while (1) {
cout << "Command Menu: " << endl;
cout << "\t$1. Insert string into list" << endl;
cout << "\t$2. Delete string from list" << endl;
cout << "\t$3. Get string from list" << endl;
cout << "\t$4. Modify string at somewhere" << endl;
cout << "\t$5. Print strings in list" << endl;
cout << "\t$6. Print length of list" << endl;
cout << "\t$7. Empty list" << endl;
cout << "\t$8. Exit this program" << endl;
cout << "\tSelect $";
int command_num;
cin >> command_num;
switch (command_num) {
case 1:
Insert();
break;
case 2:
Delete();
break;
case 3:
Get();
break;
case 4:
Modify();
break;
case 5:
PrintStrings();
break;
case 6:
PrintLengthOfList();
break;
case 7:
g_list->deleteAllElements();
break;
case 8:
delete g_list;
return 1;
default:
char temp[1024];
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
break;
}
cout << "--------------------------------------------------" << endl;
}
delete g_list;
return 0;
}
void Insert() {
int sub_command_num;
string val;
int index;
char temp[1024];
cout << "\tSub Menu: " << endl;
cout << "\t\t$1. Insert string in front" << endl;
cout << "\t\t$2. Insert string in end" << endl;
cout << "\t\t$3. Insert string in somewhere" << endl;
cout << "\t\tSelect $";
cin >> sub_command_num;
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
switch (sub_command_num) {
case 1:
cout << "\t\tType your string: ";
std::getline(std::cin, val);
g_list->insertElementInFront(AClass(val));
break;
case 2:
cout << "\t\tType your string: ";
getline(std::cin, val);
g_list->insertElementInEnd(AClass(val));
break;
case 3:
cout << "\t\tType index: ";
cin >> index;
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "\t\tType your string: ";
getline(std::cin, val);
g_list->insertElementAtIndex(AClass(val), index);
break;
default:
char temp[1024];
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
break;
}
}
void Delete() {
int sub_command_num;
string val;
int index;
cout << "\tSub Menu: " << endl;
cout << "\t\t$1. Delete string from front" << endl;
cout << "\t\t$2. Delete string from end" << endl;
cout << "\t\t$3. Delete string from somewhere" << endl;
cout << "\t\tSelect $";
cin >> sub_command_num;
switch (sub_command_num) {
case 1:
g_list->deleteElementInFront();
break;
case 2:
g_list->deleteElementInEnd();
break;
case 3:
cout << "\t\tType index: ";
cin >> index;
g_list->deleteElementAtIndex(index);
break;
default:
char temp[1024];
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
break;
}
}
void Get() {
int sub_command_num;
string val;
int index;
AClass *a = NULL;
cout << "\tSub Menu: " << endl;
cout << "\t\t$1. Get string from front" << endl;
cout << "\t\t$2. Get string from end" << endl;
cout << "\t\t$3. Get string from somewhere" << endl;
cout << "\t\tSelect $";
cin >> sub_command_num;
switch (sub_command_num) {
case 1:
try{
a = new AClass(g_list->getElementInFront());
cout << "What you get: " << a->getValue() << endl;
} catch(glist::OutOfRangeException &e) {
cout << "Exception: " << e.what() << endl;
}
break;
case 2:
try {
a = new AClass(g_list->getElementInEnd());
cout << "What you get: " << a->getValue() << endl;
} catch(glist::OutOfRangeException &e) {
cout << "Exception: " << e.what() << endl;
}
break;
case 3:
cout << "\t\tType index: ";
cin >> index;
try {
a = new AClass(g_list->getElementAtIndex(index));
cout << "What you get: " << a->getValue() << endl;
} catch(glist::OutOfRangeException &e) {
cout << "Exception: " << e.what() << endl;
}
break;
default:
char temp[1024];
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
break;
}
}
void Modify() {
string val;
int index;
cout << "\t\tType index: ";
cin >> index;
char temp[1024];
cin.getline(temp, 1024);
if (cin.fail()) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "\t\tModify that string: ";
getline(std::cin, val);
try {
(*g_list)[index].setValue(val);
} catch(glist::OutOfRangeException &e) {
cout << "Exception: " << e.what() << endl;
return;
}
}
void PrintStrings() {
cout << "List: ";
for (int i = 0; i < g_list->getLength(); i++) {
try {
AClass a = g_list->getElementAtIndex(i);
cout << a.getValue();
} catch(glist::OutOfRangeException &e) {
cout << "Exception: " << e.what() << endl;
}
if (i != g_list->getLength()-1)
cout << ", ";
}
cout << endl;
}
void PrintLengthOfList() {
cout << "Length of list: " << g_list->getLength() << endl;
}