-
Notifications
You must be signed in to change notification settings - Fork 1
/
stl_functors.cpp
executable file
·193 lines (171 loc) · 6.03 KB
/
stl_functors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Solving http://courses.cms.caltech.edu/cs11/material/advcpp/lab1/index.html
// First implementation using STL, and function objects
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iterator>
#include <functional>
using namespace std;
class my_functor
{
public:
void operator() (string s) { cout << "my_functor says: " << s << endl; }
};
int func1(void)
{
my_functor f;
f("hello world");
return 0;
}
// Create a vector of 100 ints.
// Fill it with 100 small, random integers between 1 and 100, inclusive, by using the appropriate mutating algorithm.
// Generate these numbers by passing the mutating algorithm a function object (or perhaps a simple function) that models a Generator.
// Your function object should use rand() and the modulo operator, at least.
// Since it would be nice to verify your code is working,
// use the copy algorithm to write your vector to cout via an ostream_iterator parameterized on ints.
class my_random_number_generator
{
public:
my_random_number_generator(int a, int b) : min(a), max(b) {}
int operator() () { return rand() % (max-min+1) + min; }
private:
int min;
int max;
};
int func2(void)
{
my_random_number_generator mrng(1,10);
vector<int> v(10);
cout << "size of v = " << v.size() << endl;
generate(v.begin(), v.end(), mrng);
copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
return 0;
}
// Create a new vector to hold 100 strings. Use another Generator that you write to fill it with 100 random alphabetic strings of random lengths between 5 and 15 characters inclusive.
// Sort the vector you've made using the version of sort that applies operator< to the vector. Display this sorted vector in a similar fashion to the way you displayed exercise 1's result.
// Then, re-sort the vector by length of string (ascending). You'll want to use a comparator that conforms to the Strict Weak Ordering model. Output your re-sorted vector to stdout.
class my_random_string_generator
{
public:
my_random_string_generator(int a, int b) : minlength(a), maxlength(b) {}
string operator() ()
{
int randlength = rand() % (maxlength-minlength+1) + minlength;
string str;
for (int i = 0; i < randlength; i++)
str += rand() % ('z' - 'a' + 1) + 'a';
return str;
}
private:
int minlength;
int maxlength;
};
class my_less
{
public:
bool operator() (string s1, string s2) { return s1.length() < s2.length(); }
};
int func3(void)
{
vector<string> strlist(10);
my_random_string_generator mrsg(5,15);
my_less ml;
generate(strlist.begin(), strlist.end(), mrsg);
cout << "AFTER GENERATION:\n";
copy(strlist.begin(), strlist.end(), ostream_iterator<string>(cout, "\n"));
sort(strlist.begin(), strlist.end());
cout << "AFTER FIRST SORT:\n";
copy(strlist.begin(), strlist.end(), ostream_iterator<string>(cout, "\n"));
sort(strlist.begin(), strlist.end(), ml);
cout << "AFTER SECOND SORT:\n";
copy(strlist.begin(), strlist.end(), ostream_iterator<string>(cout, "\n"));
return 0;
}
// Generate a vector of 100 random integers between 1 and 100, as before,
// then write some code to count how many of these numbers are odd and how many are even, in a single pass over the integers.
// Do this by creating a simple function object that implements the unary_function model, and that maintains some internal state.
// You should then be able to apply it with the for_each algorithm and then extract the counts at the end.
class count_odd_even
{
public:
count_odd_even() : count_odd(0), count_even(0) {}
void operator() (int a)
{
count_odd = count_odd + (a % 2);
count_even = count_even + ((a+1)%2);
}
int get_count_odd() { return count_odd; }
int get_count_even() { return count_even; }
private:
int count_odd;
int count_even;
};
int func4(void)
{
vector<int> v(10);
my_random_number_generator mrng(1,10);
count_odd_even coe;
generate(v.begin(), v.end(), mrng);
cout << "AFTER GENERATION\n";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
coe = for_each(v.begin(), v.end(), coe);
cout << " count_odd = " << coe.get_count_odd() << "\ncount_even = " << coe.get_count_even() << "\n";
return 0;
}
// what you think the author of this code intended it to do,
// why this code is broken (what does it do?),
// how you've fixed it.
// Of course, actually fix the code, compile, and verify that it works the way it was probably meant to work.
int func5(void)
{
vector<int> v;
v.push_back(1);
v.push_back(4);
v.push_back(2);
v.push_back(8);
v.push_back(5);
v.push_back(7);
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
// Now you can try your hand at writing a simple STL algorithm. You will create your own version of the reverse() algorithm in a file exercise5.cc. This algorithm must be implemented as a function template (which we will discuss in a future class), declared like this:
template <typename BidirectionalIterator>
void my_reverse(BidirectionalIterator first, BidirectionalIterator last)
{
BidirectionalIterator it1 = first;
BidirectionalIterator it2 = last;
while (it1 < it2)
{
it2--;
swap(*it1,*it2);
it1++;
}
}
int func6(int size)
{
vector<int> v(size);
my_random_number_generator mrng(1,100);
generate(v.begin(), v.end(), mrng);
cout << "AFTER GENERATE\n";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << "\n";
my_reverse(v.begin(), v.end());
cout << "AFTER REVERSE\n";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
cout << "\n";
return 0;
}
int main(void)
{
//func1();
//func2();
//func3();
//func4();
//func5();
func6(7);
return 0;
}