Skip to content

Commit 90037a7

Browse files
author
tiberius
committed
almost finished implementing exercise 3; the difference between begin()/first() and end()/last() is unclear and left for tomorrow
1 parent 0204bb0 commit 90037a7

File tree

8 files changed

+161
-60
lines changed

8 files changed

+161
-60
lines changed

cpp4j/cpp4j.pro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ HEADERS += greater.h \
1616
rationalnumberarray.h \
1717
tree.h \
1818
treeiterator.h \
19-
treenode.h
19+
treenode.h \
20+
map.h
2021
SOURCES += rationalnumber.cpp \
2122
rationalnumberarray.cpp \
2223
testMain.cpp \

cpp4j/map.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#ifndef MAP_H
2+
#define MAP_H
3+
4+
#include "pair.h"
5+
#include "tree.h"
6+
#include "treeiterator.h"
7+
8+
template <class KeyT, class ValueT, class Order> class Map {
9+
10+
public:
11+
12+
typedef Pair<KeyT, ValueT> KVPair;
13+
14+
typedef TreeIterator<KVPair, Order> iterator;
15+
typedef Tree<KVPair, Order> KVTree;
16+
17+
ValueT& operator[](const KeyT& key) {
18+
iterator i = find(key);
19+
20+
if (!i.isValid()) {
21+
ValueT dummy;
22+
KVPair kv (key, dummy);
23+
i = insert(kv);
24+
}
25+
26+
KVPair & kv = *i;
27+
return kv.second();
28+
29+
}
30+
31+
iterator insert(const Pair<KeyT,ValueT>& kv) {
32+
iterator i = find(kv.first());
33+
if (i.isValid()) {
34+
// update
35+
*i = kv;
36+
} else {
37+
i = m_tree.insert(kv);
38+
}
39+
40+
return i;
41+
}
42+
43+
iterator find(const KeyT& key) {
44+
ValueT dummy;
45+
KVPair kv (key, dummy);
46+
return m_tree.find(kv);
47+
}
48+
49+
iterator begin() {
50+
return m_tree.begin();
51+
}
52+
53+
iterator end() {
54+
return m_tree.end();
55+
}
56+
57+
iterator first() {
58+
return m_tree.first();
59+
}
60+
61+
iterator last() {
62+
return m_tree.last();
63+
}
64+
65+
const KeyT& min() {
66+
return first()->first();
67+
}
68+
69+
const KeyT& max() {
70+
return last()->first();
71+
}
72+
73+
void clear() {
74+
m_tree.clear();
75+
}
76+
77+
private:
78+
79+
KVTree m_tree;
80+
81+
};
82+
83+
#endif // MAP_H

cpp4j/maptofirst.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
#include "pair.h"
55

66
// int string less
7-
template <class T1, class T2, template<class> class Order > class MapToFirst {
7+
template <class T1, class T2, class Order > class MapToFirst {
88

99
public:
1010

1111
//int,string
1212
bool operator ()(const Pair<T1,T2> &left, const Pair<T1,T2> &right){
13-
Order<T1> functor; // less<int>
13+
Order functor; // less<int>
1414
return functor(left.first(),right.first());
1515
}
1616

cpp4j/pair.h

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,17 @@ template <class T1, class T2> class Pair {
77

88
public :
99

10-
Pair ():
11-
m_first(),
12-
m_second()
13-
{ }
14-
15-
Pair (T1 firstParam, T2 secondParam):
16-
m_first(firstParam),
17-
m_second(secondParam)
18-
{ }
19-
20-
Pair (Pair <T1,T2>& otherPair):
21-
m_first(otherPair.first()),
22-
m_second(otherPair.second())
23-
{ }
24-
25-
Pair& operator=
26-
(const Pair &right){
27-
return Pair(right.first(), right.second());
10+
Pair (): m_first(), m_second() { }
11+
12+
Pair (T1 firstParam, T2 secondParam): m_first(firstParam), m_second(secondParam) { }
13+
14+
Pair (const Pair <T1,T2>& otherPair): m_first(otherPair.first()), m_second(otherPair.second()) { }
15+
Pair (Pair <T1,T2>& otherPair): m_first(otherPair.first()), m_second(otherPair.second()) { }
16+
17+
Pair& operator= (const Pair &right){
18+
m_first = right.first();
19+
m_second = right.second();
20+
return *this;
2821
}
2922

3023
friend ostream& operator<< (ostream &os, const Pair<T1,T2>& pair){
@@ -50,7 +43,7 @@ public :
5043

5144
private:
5245

53-
T1 m_first ;
46+
T1 m_first;
5447
T2 m_second;
5548

5649
};

cpp4j/testTemplates.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ using namespace std;
1919
#include "maptofirst.h"
2020
//#include "order.h"
2121
#include "tree.h"
22-
//#include "map.h"
22+
#include "map.h"
2323

2424
// you should define your own namespace for
2525
// the templates/classes in this project
@@ -91,7 +91,7 @@ int testTemplates(void)
9191

9292
/////////////////////////////////////////
9393
// TEST PAIR ORDER
94-
MapToFirst< int, float, Less > lessPair;
94+
MapToFirst< int, float, Less<int> > lessPair;
9595
cout << i_f << " < " << i_f2 << " == " << lessPair(i_f, i_f2) << endl;
9696
assert(lessPair(i_f, i_f2));
9797

@@ -156,7 +156,7 @@ int testTemplates(void)
156156

157157
// now we contruct a tree with a "reverse" order
158158
//typedef Tree< float, Greater<float> > RevFloatTree; // had to replace this line by the following
159-
typedef Tree< float, Greater > RevFloatTree;
159+
typedef Tree< float, Greater<float> > RevFloatTree;
160160
RevFloatTree ft;
161161
ft.insert(3.1);
162162
ft.insert(6.2);
@@ -165,18 +165,11 @@ int testTemplates(void)
165165
cout << "reverse-sorted 4-float tree: ";
166166
assert(printAndCount(ft) == 4);
167167

168-
RevFloatTree::iterator beginIt = ft.begin();
169-
RevFloatTree::iterator endIt = ft.end();
170-
cout << *beginIt;
171-
cout << *endIt;
172-
173168
// if we list elements backwards, they should be
174169
// in the same order as with the function Less<>
175170
cout << "listing backwards: ";
176171
assert(printAndCountBackwards(ft) == 4);
177172

178-
#if 0 // move this line down while your implementation proceeds...
179-
180173
/////////////////////////////////////////
181174
// TEST MAP
182175

@@ -186,8 +179,7 @@ int testTemplates(void)
186179
Pair<int,string> p7(7,"James Bond");
187180
string value;
188181

189-
Map<int,string, MapToFirst<int,string,Less> > m;
190-
182+
Map<int,string, MapToFirst<int, string, Less<int> > > m;
191183
// insert pairs of (key,value)
192184
m.insert(p42);
193185
m.insert(p7);
@@ -204,22 +196,27 @@ int testTemplates(void)
204196
cout << "setting m[3] and m[1]." << endl;
205197
m[1] = p1.second();
206198
m[3] = p3.second();
199+
cout << "find 1 in map: " << (value=m[1]) << endl;
200+
assert(value == p1.second());
207201
cout << "find 3 in map: " << (value=m[3]) << endl;
208202
assert(value == p3.second());
209203

210204
cout << "resulting map: ";
211205
assert(printAndCount(m) == 4);
212206

213207
// test first() and last(), min() and max()
214-
Map<int,string>::iterator first = m.first();
215-
Map<int,string>::iterator last = m.last();
208+
Map<int,string, MapToFirst<int, string, Less<int> > >::iterator first = m.first();
209+
Map<int,string, MapToFirst<int, string, Less<int> > >::iterator last = m.last();
216210
cout << "first in map: " << *first << endl;
217211
cout << "last in map: " << *last << endl;
218212
assert(first->first() == 1);
219213
assert(last->first() == 42);
220214
assert(m.min() == first->first());
221215
assert(m.max() == last->first());
222216

217+
#if 0 // move this line down while your implementation proceeds...
218+
219+
223220
#endif
224221

225222
cout << "Success!" << endl;

cpp4j/tree.h

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@
55
#include "treeiterator.h"
66
#include "treenode.h"
77

8-
template <class T, template<class> class Order = Less > class Tree {
8+
template <class T, class Order = Less<T> > class Tree {
99

1010
public:
1111

1212
Tree():m_root(NULL) {}
1313

1414
typedef TreeIterator<T,Order> iterator;
15-
typedef TreeNode<T,Order> node;
15+
//typedef TreeNode<T,Order> node;
1616

1717
iterator insert(const T& value) {
1818

1919
if (m_root == NULL) {
20-
m_root = new node(value);
20+
m_root = new TreeNode<T, Order>(value);
2121
return begin();
2222
} else {
2323
return insert_internal (iterator (m_root, this), value);
@@ -47,21 +47,29 @@ template <class T, template<class> class Order = Less > class Tree {
4747
return iterator (node, this, iterator::end);
4848
}
4949

50-
/*iterator first();
51-
iterator last();
52-
iterator find(const T& value);*/
50+
const iterator first() const {
51+
return begin();
52+
}
53+
54+
const iterator last() const {
55+
return end();
56+
}
57+
58+
iterator find(const T& value) {
59+
return find_internal(iterator (m_root, this, iterator::middle), value);
60+
}
5361

5462

5563
protected:
5664
TreeNode<T, Order> * m_root;
5765

5866
iterator insert_internal(iterator i, const T& value) {
59-
Order<T> order;
67+
Order order;
6068

6169
if (order(value, i.m_node->m_value)) { // links
6270
iterator prev = iterator (i.m_node->m_left, this);
6371
if (prev.m_node == NULL) {
64-
prev.m_node = new node(value);
72+
prev.m_node = new TreeNode<T,Order>(value);
6573
prev.m_node->m_up = i.m_node;
6674
i.m_node->m_left = prev.m_node;
6775
return prev;
@@ -73,7 +81,7 @@ template <class T, template<class> class Order = Less > class Tree {
7381
} else if (order(i.m_node->m_value, value)) { // rechts
7482
iterator next = iterator (i.m_node->m_right, this);
7583
if (next.m_node == NULL) {
76-
next.m_node = new node(value);
84+
next.m_node = new TreeNode<T,Order>(value);
7785
next.m_node->m_up = i.m_node;
7886
i.m_node->m_right = next.m_node;
7987
return next;
@@ -88,6 +96,23 @@ template <class T, template<class> class Order = Less > class Tree {
8896
}
8997
}
9098

99+
iterator find_internal (iterator i, const T& value) {
100+
if (i.m_node == NULL)
101+
return i;
102+
103+
Order order;
104+
105+
const bool left = order(value, i.m_node->m_value);
106+
const bool right = order(i.m_node->m_value, value);
107+
108+
if (left)
109+
return find_internal(iterator(i.m_node->m_left, this), value);
110+
111+
if (right)
112+
return find_internal(iterator(i.m_node->m_right, this), value);
113+
114+
return i;
115+
}
91116

92117
};
93118

cpp4j/treeiterator.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,28 @@
33

44
#include "treenode.h"
55

6-
template <class T, template<typename> class Order > class Tree;
6+
template <class T, class Order > class Tree;
77

8-
template <class T, template<typename> class Order > class TreeIterator {
8+
template <class T, class Order > class TreeIterator {
99

1010
friend class Tree<T, Order>;
1111

1212
public:
1313

14+
enum iteration_mode { begin, middle, end };
15+
TreeIterator(TreeNode<T, Order> * node, const Tree<T, Order> * tree, const iteration_mode mode = middle)
16+
: m_mode(mode), m_node(node), m_tree(tree) {}
17+
18+
bool isValid(void) {
19+
return m_node != NULL;
20+
}
21+
1422
T& operator*() {
1523
return m_node->value();
1624
}
1725

1826
T* operator->() {
19-
return m_node->value();
27+
return &m_node->m_value;
2028
}
2129

2230
// zum nächsten Element
@@ -71,7 +79,7 @@ template <class T, template<typename> class Order > class TreeIterator {
7179
if (m_node == NULL || m_mode == begin)
7280
return *this;
7381

74-
m_mode == middle;
82+
m_mode = middle;
7583

7684
if (m_node->m_left != NULL) {
7785
m_node = m_node->m_left;
@@ -122,18 +130,12 @@ template <class T, template<typename> class Order > class TreeIterator {
122130

123131
protected:
124132

125-
enum iteration_mode { begin, middle, end };
126133
iteration_mode m_mode;
127134

128-
TreeIterator(TreeNode<T, Order> * node, const Tree<T, Order> * tree)
129-
: m_node(node), m_tree(tree), m_mode(middle) {}
130-
131-
TreeIterator(TreeNode<T, Order> * node, const Tree<T, Order> * tree, const iteration_mode mode)
132-
: m_node(node), m_tree(tree), m_mode(mode) {}
135+
TreeNode<T, Order> * m_node;
133136

134137
private:
135138

136-
TreeNode<T, Order> * m_node;
137139
const Tree<T, Order> * m_tree;
138140
};
139141

0 commit comments

Comments
 (0)