Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b8654e9

Browse files
committed
Exercise 26.5; Exercise 26.6
1 parent cad021c commit b8654e9

File tree

6 files changed

+1319
-0
lines changed

6 files changed

+1319
-0
lines changed

‎Chapter_26/C26_Exercise_26.5.cpp

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
/* Exercise 26.5 */
2+
3+
#include<iostream>
4+
#include<sstream>
5+
#include<fstream>
6+
#include<iomanip>
7+
#include<vector>
8+
#include"C26_Exercise_26.5.h"
9+
10+
using namespace std;
11+
12+
inline void error(string s) { throw runtime_error(s); }
13+
inline void error(const string& s, const string& s2) { error(s + s2); }
14+
inline void error(const string& s, int i) { ostringstream os; os << s << ": " << i; error(os.str()); }
15+
inline void keep_window_open() { char ch; cin >> ch; }
16+
inline int randint(int max) { return rand() % max; }
17+
inline int randint(int min, int max) { return randint(max - min) + min; }
18+
19+
int main()
20+
{
21+
enum Action {
22+
EXIT = -1, PRINTACTIONLIST,
23+
CASE1, CASE2, CASE3, CASE4, CASE5, CASE6, CASE7, CASE8, CASE9, CASE10
24+
};
25+
const string actionList = "\tList of actions:\n"
26+
" (1) Test BinarySearch()\n"
27+
" (-1) Exit, (0) Print the list of actions\n";
28+
cout << actionList;
29+
int action;
30+
bool cond{ true };
31+
while (cond) try {
32+
cout << "\nPlease enter the action: ";
33+
if (!(cin >> action)) { ClearInput(cin); error("Error. Incorrect input"); }
34+
char ch;
35+
cin.get(ch);
36+
switch (action) {
37+
case CASE1: {
38+
cout << endl;
39+
{
40+
string fileInput{ "C26_Exercise_26.4_test_int.txt" };
41+
ifstream ifs{ fileInput };
42+
if (!ifs) error("Error. Can't open input file: ", fileInput);
43+
TestAll<int>(ifs, cout, fileInput);
44+
45+
// Test 8 "Sets generated using random numbers"
46+
constexpr int numberOfElements = 50;
47+
constexpr int spread = 20;
48+
stringstream ss;
49+
for (int i = 1; i <= 20; ++i) {
50+
vector<int> v;
51+
int sum = 0;
52+
for (int j = 0; j < numberOfElements; ++j) {
53+
sum += randint(spread);
54+
v.push_back(sum);
55+
}
56+
int x = v[randint(v.size())];
57+
ss << "{ 8." << i << " " << x << " 1 1 { ";
58+
for (int j = 0; j < v.size(); ++j) {
59+
ss << v[j] << " ";
60+
}
61+
ss << "} random ints }" << endl;
62+
}
63+
TestAll<int>(ss, cout, "Sets generated using random numbers");
64+
}
65+
66+
{
67+
string fileInput{ "C26_Exercise_26.4_test_double.txt" };
68+
ifstream ifs{ fileInput };
69+
if (!ifs) error("Error. Can't open input file: ", fileInput);
70+
TestAll<double>(ifs, cout, fileInput);
71+
72+
// Test 8 "Sets generated using random numbers"
73+
constexpr int numberOfElements = 50;
74+
constexpr int spread = 20;
75+
stringstream ss;
76+
for (int i = 1; i <= 20; ++i) {
77+
vector<double> v;
78+
double sum = 0;
79+
for (int j = 0; j < numberOfElements; ++j) {
80+
sum += double(randint(spread)) + double(randint(1, 99)) / 100;
81+
v.push_back(sum);
82+
}
83+
double x = v[randint(v.size())];
84+
ss << "{ 8." << i << " " << x << " 1 1 { ";
85+
for (int j = 0; j < v.size(); ++j) {
86+
ss << v[j] << " ";
87+
}
88+
ss << "} random doubles }" << endl;
89+
}
90+
TestAll<double>(ss, cout, "Sets generated using random numbers");
91+
}
92+
93+
{
94+
string fileInput{ "C26_Exercise_26.4_test_string.txt" };
95+
ifstream ifs{ fileInput };
96+
if (!ifs) error("Error. Can't open input file: ", fileInput);
97+
TestAll<string>(ifs, cout, fileInput);
98+
99+
// Test 8 "Sets generated using random numbers"
100+
constexpr int numberOfLetters = 'z' - 'a' + 1;
101+
constexpr int maxLetters = 5;
102+
constexpr char firstLetter = 'a';
103+
stringstream ss;
104+
for (int i = 1; i <= 20; ++i) {
105+
vector<string> v;
106+
string s;
107+
for (int j = 0; j < numberOfLetters; ++j) {
108+
s = "";
109+
s += firstLetter + j;
110+
for (int k = 1; k < maxLetters; ++k) {
111+
s += char(randint('a', 'z' + 1));
112+
}
113+
v.push_back(s);
114+
}
115+
string x = v[randint(v.size())];
116+
ss << "{ 8." << i << " " << x << " 1 1 { ";
117+
for (int j = 0; j < v.size(); ++j) {
118+
ss << v[j] << " ";
119+
}
120+
ss << "} random strings }" << endl;
121+
}
122+
TestAll<string>(ss, cout, "Sets generated using random numbers");
123+
}
124+
125+
cout << vsp_2;
126+
break;
127+
}
128+
case PRINTACTIONLIST:
129+
cout << actionList;
130+
break;
131+
case EXIT:
132+
cond = false;
133+
break;
134+
default:
135+
error("Error. Incorrect action number");
136+
break;
137+
}
138+
}
139+
catch (runtime_error& e) {
140+
cerr << e.what() << endl;
141+
}
142+
catch (...) {
143+
cerr << "Error. Exception\n";
144+
return 1;
145+
}
146+
return 0;
147+
}
148+
149+
void ClearInput(istream& is)
150+
{
151+
is.clear();
152+
is.ignore(numeric_limits<streamsize>::max(), '\n');
153+
}
154+
155+
template<class T> istream& operator>>(istream& is, Test<T>& t)
156+
{
157+
Test<T> test;
158+
constexpr char cbLeft{ '{' }; // cb - curly brace
159+
constexpr char cbRigth{ '}' }; // cb - curly brace
160+
char ch1, ch2;
161+
while (true) {
162+
is >> ch1;
163+
if (!is) return is;
164+
if (ch1 == '#') {
165+
string s;
166+
getline(is, s);
167+
}
168+
else break;
169+
}
170+
is >> test.lab >> test.val >> test.res >> test.typ >> ch2;
171+
if (!is) return is;
172+
if (ch1 != cbLeft || ch2 != cbLeft) {
173+
is.setstate(ios::failbit);
174+
return is;
175+
}
176+
while (true) {
177+
char ch3;
178+
is >> ch3;
179+
if (!is) return is;
180+
if (ch3 == cbRigth) break;
181+
is.unget();
182+
T val;
183+
is >> val;
184+
if (!is) return is;
185+
test.seq.push_back(val);
186+
}
187+
while (true) {
188+
string s;
189+
is >> s;
190+
if (!is) return is;
191+
if (s.size() == 1 && s[0] == cbRigth) break;
192+
test.desc += ((test.desc.size() > 0) ? (" " + s) : s);
193+
}
194+
t = test;
195+
return is;
196+
}
197+
198+
template<class T> int TestAll(istream& is, ostream& os, const string& description)
199+
{
200+
os << sp_2 << description << endl;
201+
int testCount = 0;
202+
int errorCount = 0;
203+
for (Test<T> t; is >> t; ) {
204+
vector<T> seq2(t.seq.size());
205+
for (int i = 0; i < t.seq.size(); ++i) {
206+
seq2[seq2.size() - i - 1] = t.seq[i];
207+
}
208+
vector<T> copy1(t.seq.size());
209+
copy(t.seq.begin(), t.seq.end(), copy1.begin());
210+
vector<T> copy2(t.seq.size());
211+
copy(seq2.begin(), seq2.end(), copy2.begin());
212+
213+
vector<T>* forward = nullptr;
214+
vector<T>* reverse = nullptr;
215+
vector<T>* forwardCopy = nullptr;
216+
vector<T>* reverseCopy = nullptr;
217+
if (t.typ) {
218+
forward = &t.seq;
219+
reverse = &seq2;
220+
forwardCopy = &copy1;
221+
reverseCopy = &copy2;
222+
}
223+
else {
224+
forward = &seq2;
225+
reverse = &t.seq;
226+
forwardCopy = &copy2;
227+
reverseCopy = &copy1;
228+
}
229+
230+
bool r = BinarySearch(forward->begin(), forward->end(), t.val);
231+
if (r != t.res) {
232+
PrintFailTest(os, t, "BinarySearch()");
233+
++errorCount;
234+
}
235+
r = BinarySearch(forward->begin(), forward->end(), t.val,
236+
[](const T& x, const T& y) { return (x < y); });
237+
if (r != t.res) {
238+
PrintFailTest(os, t, "BinarySearch(Compare(x < y))");
239+
++errorCount;
240+
}
241+
r = BinarySearch(reverse->begin(), reverse->end(), t.val,
242+
[](const T& x, const T& y) { return (x > y); });
243+
if (r != t.res) {
244+
PrintFailTest(os, t, "BinarySearch(Compare(x > y))");
245+
++errorCount;
246+
}
247+
bool match = true;
248+
for (auto it = forward->begin(), itCopy = forwardCopy->begin(); it != forward->end(); ++it, ++itCopy) {
249+
if (*it != *itCopy) {
250+
++errorCount;
251+
match = false;
252+
break;
253+
}
254+
}
255+
for (auto it = reverse->begin(), itCopy = reverseCopy->begin(); it != reverse->end(); ++it, ++itCopy) {
256+
if (*it != *itCopy) {
257+
++errorCount;
258+
match = false;
259+
break;
260+
}
261+
}
262+
if (match == false) {
263+
os << "Test " << t.lab << " ";
264+
if (t.desc.size() > 0) os << "(" << t.desc << ") ";
265+
os << "modifies the sequence" << endl;
266+
}
267+
++testCount;
268+
}
269+
if (!is && !is.eof()) os << sp_6 << "Invalid test" << endl;
270+
os << sp_4 << errorCount << " error(s), " << testCount << " test(s)" << endl;
271+
return errorCount;
272+
}
273+
274+
template<class T> void PrintFailTest(ostream& os, const Test<T>& t, const string& description)
275+
{
276+
if (description.size() > 0) os << description;
277+
else os << "Test";
278+
os << " failed: " << t.lab << " ";
279+
if (t.desc.size() > 0) os << "(" << t.desc << ") ";
280+
os << "Sequence { ";
281+
for (const T& x : t.seq) os << x << ' ';
282+
os << "} Target value { " << t.val << " } Is the value in the sequence { "
283+
<< boolalpha << t.res << noboolalpha << " }" << endl;
284+
}
285+
286+
template<class RandomAccessIterator, class T>
287+
bool BinarySearch(RandomAccessIterator first, RandomAccessIterator last, const T& x)
288+
{
289+
using Iter = RandomAccessIterator;
290+
if (first == last) return false;
291+
--last;
292+
while (first <= last) {
293+
Iter middle = (last - first) / 2 + first;
294+
if (*middle == x) return true;
295+
else if (*middle > x) last = middle - 1;
296+
else first = middle + 1; // *middle < x
297+
}
298+
return false;
299+
}
300+
301+
template<class RandomAccessIterator, class T, class Compare>
302+
bool BinarySearch(RandomAccessIterator first, RandomAccessIterator last, const T& x, Compare comp)
303+
{
304+
using Iter = RandomAccessIterator;
305+
if (first == last) return false;
306+
--last;
307+
while (first <= last) {
308+
Iter middle = (last - first) / 2 + first;
309+
if (comp(x, *middle)) last = middle - 1;
310+
else if (comp(*middle, x)) first = middle + 1;
311+
else return true;
312+
}
313+
return false;
314+
}

‎Chapter_26/C26_Exercise_26.5.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* Exercise 26.5 */
2+
3+
using namespace std;
4+
5+
const char* sp_2 = " ";
6+
const char* sp_4 = " ";
7+
const char* sp_6 = " ";
8+
const char* sp_8 = " ";
9+
const char* vsp_2 = "\n\n";
10+
const char* vsp_3 = "\n\n\n";
11+
const char* vsp_4 = "\n\n\n\n";
12+
13+
void ClearInput(istream& is);
14+
15+
/*
16+
Test case format:
17+
# (at the beginning of the line) - comment, skip to end of line
18+
{ L TV R T { V1 V2 V3 ... } D }
19+
L - <string> label, without space
20+
TV - <T> target value, valid value from the sequence
21+
R - <bool> the expected result of the search: '1' - found, '0' - not found
22+
T - <bool> type of ordered sequence: '1' - smallest-to-largest, '0' - largest-to-smallest
23+
V1, V2, V3 ... - <T> sequence of values to search for
24+
D - <string> description, read until it encounters a '}'
25+
*/
26+
template<class T> struct Test {
27+
string lab; // label, mark or number
28+
string desc; // description
29+
T val; // valid value from the sequence
30+
vector<T> seq; // element sequence
31+
bool res; // result, is the value in the sequence, 1 (true) or 0 (false)
32+
bool typ; // type of ordered sequence, 1 (smallest-to-largest) or 0 (largest-to-smallest)
33+
};
34+
35+
template<class T> istream& operator>>(istream& is, Test<T>& t);
36+
37+
template<class T> int TestAll(istream& is, ostream& os, const string& description);
38+
template<class T> void PrintFailTest(ostream& os, const Test<T>& t, const string& description);
39+
40+
template<class RandomAccessIterator, class T>
41+
bool BinarySearch(RandomAccessIterator first, RandomAccessIterator last, const T& x);
42+
template<class RandomAccessIterator, class T, class Compare>
43+
bool BinarySearch(RandomAccessIterator first, RandomAccessIterator last, const T& x, Compare comp);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /