├── .gitignore
├── Chapter 00
├── README.md
├── q00.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q06.cpp
├── q08.cpp
├── q09.cpp
└── q10.cpp
├── Chapter 01
├── README.md
└── q05.cpp
├── Chapter 02
├── README.md
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q07.cpp
├── q08.cpp
└── q09.cpp
├── Chapter 03
├── README.md
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
└── q06.cpp
├── Chapter 04
├── README.md
├── Student_info.cpp
├── Student_info.h
├── grade.cpp
├── grade.h
├── median.cpp
├── median.h
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05-1.cpp
├── q05-2.cpp
├── q06.cpp
├── q07.cpp
├── read_words.cpp
└── read_words.h
├── Chapter 05
├── 10.txt
├── 1000.txt
├── 10000.txt
├── README.md
├── Rotation.cpp
├── Rotation.h
├── frame.cpp
├── frame.h
├── q01.cpp
├── q02-1.cpp
├── q02-2.cpp
├── q03.cpp
├── q05.cpp
├── q06.cpp
├── q07.cpp
├── q08.cpp
├── q09.cpp
├── q10.cpp
├── q11.cpp
├── split.cpp
└── split.h
├── Chapter 06
├── README.md
├── Student_info.cpp
├── Student_info.h
├── analysis.cpp
├── analysis.h
├── find_urls.cpp
├── find_urls.h
├── grade.cpp
├── grade.h
├── median.cpp
├── median.h
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q06.cpp
├── q07.cpp
├── q08.cpp
└── q09.cpp
├── Chapter 07
├── README.md
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q06.cpp
├── q07.cpp
├── q08.cpp
└── q09.cpp
├── Chapter 08
├── README.md
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05-1.cpp
└── q05-2.cpp
├── Chapter 09
├── README.md
├── Student_info.cpp
├── Student_info.h
├── Student_info_ex.cpp
├── Student_info_ex.h
├── Student_info_pf.cpp
├── Student_info_pf.h
├── q01.cpp
├── q03-1.cpp
├── q03-2.cpp
├── q04.cpp
├── q05.cpp
└── q06.cpp
├── Chapter 10
├── README.md
├── String_list.cpp
├── String_list.h
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q06.cpp
├── split.cpp
└── split.h
├── Chapter 11
├── Lis.h
├── README.md
├── Student_info.cpp
├── Student_info.h
├── Student_info_ex_vec.cpp
├── Student_info_ex_vec.h
├── Student_info_pf_vec.cpp
├── Student_info_pf_vec.h
├── Student_info_vec.cpp
├── Student_info_vec.h
├── Vec.h
├── grade.cpp
├── grade.h
├── median.cpp
├── median.h
├── q05-1.cpp
├── q05-2.cpp
├── q05-3.cpp
├── q05-4.cpp
├── q07-1.cpp
├── q07-2.cpp
├── q07-3.cpp
├── q07-4.cpp
├── q07-5.cpp
├── q07-6.cpp
├── q07-7.cpp
├── q08.cpp
└── q09.cpp
├── Chapter 12
├── README.md
├── Str.cpp
├── Str.h
├── Str_Vec.cpp
├── Str_Vec.h
├── Vec.h
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q06.cpp
├── q07.cpp
├── q08.cpp
├── q09.cpp
├── q10.cpp
├── q11.cpp
├── q12.cpp
├── q13.cpp
├── q14.cpp
└── q15.cpp
├── Chapter 13
├── README.md
├── Student_info.cpp
├── Student_info.h
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
├── q08.cpp
└── student_list.txt
├── Chapter 14
├── Ptr.h
├── Ptr_Ctr.h
├── README.md
├── Str.cpp
├── Str.h
├── Str_Ctr.cpp
├── Str_Ctr.h
├── Student_info.cpp
├── Student_info.h
├── compare_Core_ptrs.cpp
├── compare_Core_ptrs.h
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q05.cpp
└── q06.cpp
├── Chapter 15
├── Pic.cpp
├── Pic.h
├── Pic_Re.cpp
├── Pic_Re.h
├── README.md
├── q01.cpp
├── q02.cpp
├── q03.cpp
├── q04.cpp
├── q05.cpp
└── q06.cpp
├── Chapter 16
├── README.md
└── q01.cpp
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
34 | # VSCode
35 | .vscode/*
36 | .vscode/settings.json
37 | .vscode/tasks.json
38 | .vscode/launch.json
39 | .vscode/extensions.json
40 | *.code-workspace
41 |
42 | # Local History for Visual Studio Code
43 | .history/
44 | .vscode/tasks.json
45 | .vscode/launch.json
--------------------------------------------------------------------------------
/Chapter 00/README.md:
--------------------------------------------------------------------------------
1 | ## Questions and Solutions
2 |
3 | ### Q0: Compile and run the `Hello, world!` program.
4 |
5 | The code can be found on [q00.cpp](./q00.cpp). You have to build it using a compiler you are using (for example g++). After you have built the program, run the output file (Double click the .exe file if you are using Windows).
6 |
7 | ### Q1: What does the following statement do?
8 | ```
9 | 3 + 4;
10 | ```
11 | This statement yields an int with a value of 7. Note that this value is not saved anywhere.
12 |
13 | ### Q2: Write a program that, when run, writes
14 | ```
15 | This (") is a quote, and this (\) is a backslash.
16 | ```
17 | The solution can be found in [q02.cpp](./q02.cpp). The trick here is using escape characters such as **\\"** and **\\\\** to print characters that might otherwise break the string.
18 |
19 | ### Q3: The string literal "`\t`" represents a tab character; different C++ implementations display tabs in different ways. Experiment with your implementation to learn how it treats tabs.
20 | A sample program for this question can be found in [q03.cpp](./q03.cpp). It seems g++ uses 8 spaces for a tab. You will see that the output has 7 spaces between the parentheses, as the closing parenthesis is put on the 8th space.
21 |
22 | ### Q4: Write a program that, when run, writes the `Hello, world!` program as its output.
23 | The solution can be found in [q04.cpp](./q04.cpp). Four spaces are used instead of tabs to make the output similar to the original code written in VSCode.
24 |
25 | ### Q5: Is this a valid program? Why or why not?
26 | ```
27 | #include
28 | int main() std::cout << "Hello, world!" << std::endl;
29 | ```
30 | This is not a valid program as the curly braces which should be present after the main function are missing. We get a compile-time error regarding this issue.
31 |
32 | ### Q6: Is this a valid program? Why or why not?
33 | ```
34 | #include
35 |
36 | int main() {{{{{{ std::cout << "Hello, world!" << std::endl; }}}}}}
37 | ```
38 | This is a valid program, as the curly brackets can be stacked indefinitely. One pair of curly brackets was enough but more can be used for other matters such as limiting the scope of a variable. The unnecessary brackets were probably ignored by the compiler. The code is present in [q06.cpp](./q06.cpp) to experiment.
39 |
40 | ### Q7: What about this one?
41 | ```
42 | #include
43 |
44 | int main()
45 | {
46 | /* This is a comment that extends over several lines
47 | because it use /* and */ as its starting and ending delimiters */
48 | std::cout << "Does this work?" << std::endl;
49 | return 0;
50 | }
51 | ```
52 | This is not a valid program, as the first ***/** in the comment closes the multi-line comment. The words after that remain outside the comment block, causing errors.
53 |
54 | ### Q8: ...and this one?
55 | ```
56 | #include
57 |
58 | int main()
59 | {
60 | // This is a comment that extends over several lines
61 | // by using // at the beginning of each line instead of using /*
62 | // or */ to delimit comments.
63 | std::cout << "Does this work?" << std::endl;
64 | return 0;
65 | }
66 | ```
67 | This is a valid program. The code can be found in [q08.cpp](./q08.cpp) to experiment.
68 |
69 | ### Q9: What is the shortest valid program?
70 | The shortest valid program is `main(){}`. The code is in [q09.cpp](./q09.cpp) to experiment.
71 |
72 | ### Q10: Rewrite the `Hello, world!` program so that a newline occurs everywhere that whitespace is allowed in the program.
73 | The program can be found in [q10.cpp](./q10.cpp).
--------------------------------------------------------------------------------
/Chapter 00/q00.cpp:
--------------------------------------------------------------------------------
1 | // code is taken from §0/1
2 |
3 | // a small C++ program
4 | #include
5 |
6 | int main()
7 | {
8 | std::cout << "Hello, world!" << std::endl;
9 | return 0;
10 | }
--------------------------------------------------------------------------------
/Chapter 00/q02.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | std::cout << "This (\") is a quote, and this (\\) is a backslash." << std::endl;
6 | return 0;
7 | }
--------------------------------------------------------------------------------
/Chapter 00/q03.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | std::cout << "A single tab is (\t)." << std::endl;
6 | return 0;
7 | }
--------------------------------------------------------------------------------
/Chapter 00/q04.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | std::cout << "// a small C++ program" << std::endl
6 | << "#include " << std::endl << std::endl
7 | << "int main()" << std::endl << "{" << std::endl
8 | << " std::cout << \"Hello, world!\" << std::endl;"
9 | << std::endl << " return 0;" << std::endl << "}";
10 | return 0;
11 | }
--------------------------------------------------------------------------------
/Chapter 00/q06.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | int main() {{{{{{ std::cout << "Hello, world!" << std::endl; }}}}}}
--------------------------------------------------------------------------------
/Chapter 00/q08.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | int main()
3 | {
4 | // This is a comment that extends over several lines
5 | // by using // at the beginning of each line instead of using /*
6 | // or */ to delimit comments.
7 | std::cout << "Does this work?" << std::endl;
8 | return 0;
9 | }
--------------------------------------------------------------------------------
/Chapter 00/q09.cpp:
--------------------------------------------------------------------------------
1 | main(){}
--------------------------------------------------------------------------------
/Chapter 00/q10.cpp:
--------------------------------------------------------------------------------
1 | // a small C++ program
2 | #include
3 | int
4 | main
5 | (
6 | )
7 | {
8 | std
9 | ::
10 | cout
11 | <<
12 | "Hello, world!"
13 | <<
14 | std
15 | ::
16 | endl
17 | ;
18 | return
19 | 0
20 | ;
21 | }
--------------------------------------------------------------------------------
/Chapter 01/q05.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main()
5 | {
6 | { std::string s = "a string";
7 | std::string x = s + ", really";
8 | std::cout << s << std::endl;
9 | std::cout << x << std::endl; }
10 | return 0;
11 | }
--------------------------------------------------------------------------------
/Chapter 02/q01.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // say what standard-library names we use
5 | using std::cin; using std::endl;
6 | using std::cout; using std::string;
7 |
8 | int main()
9 | {
10 | // ask for the person's name
11 | cout << "Please enter your first name: ";
12 |
13 | // read the name
14 | string name;
15 | cin >> name;
16 |
17 | // build the message that we intend to write
18 | const string greeting = "Hello, " + name + "!";
19 |
20 | // the number of blanks surrounding the greeting
21 | const int pad = 0;
22 |
23 | // the number of rows and columns to write
24 | const int rows = pad * 2 + 3;
25 | const string::size_type cols = greeting.size() + pad * 2 + 2;
26 |
27 | // write a blank line to separate the output from the input
28 | cout << endl;
29 |
30 | // write rows rows of output
31 | // invariant: we have written r rows so far
32 | for (int r = 0; r != rows; ++r) {
33 |
34 | string::size_type c = 0;
35 |
36 | // invariant: we have written c characters so far in the current row
37 | while (c != cols) {
38 |
39 | // is it time to write the greeting?
40 | if (r == pad + 1 && c == pad + 1) {
41 | cout << greeting;
42 | c += greeting.size();
43 | } else {
44 |
45 | // are we on the border?
46 | if (r == 0 || r == rows - 1 ||
47 | c == 0 || c == cols - 1)
48 | cout << "*";
49 | else
50 | cout << " ";
51 | ++c;
52 | }
53 | }
54 | cout << endl;
55 | }
56 | return 0;
57 | }
--------------------------------------------------------------------------------
/Chapter 02/q02.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // say what standard-library names we use
5 | using std::cin; using std::endl;
6 | using std::cout; using std::string;
7 |
8 | int main()
9 | {
10 | // ask for the person's name
11 | cout << "Please enter your first name: ";
12 |
13 | // read the name
14 | string name;
15 | cin >> name;
16 |
17 | // build the message that we intend to write
18 | const string greeting = "Hello, " + name + "!";
19 |
20 | // the number of blanks surrounding the greeting
21 | const int pad_vertical = 1;
22 | const int pad_horizontal = 2;
23 |
24 | // the number of rows and columns to write
25 | const int rows = pad_vertical * 2 + 3;
26 | const string::size_type cols = greeting.size() + pad_horizontal * 2 + 2;
27 |
28 | // write a blank line to separate the output from the input
29 | cout << endl;
30 |
31 | // write rows rows of output
32 | // invariant: we have written r rows so far
33 | for (int r = 0; r != rows; ++r) {
34 |
35 | string::size_type c = 0;
36 |
37 | // invariant: we have written c characters so far in the current row
38 | while (c != cols) {
39 |
40 | // is it time to write the greeting?
41 | if (r == pad_vertical + 1 && c == pad_horizontal + 1) {
42 | cout << greeting;
43 | c += greeting.size();
44 | } else {
45 |
46 | // are we on the border?
47 | if (r == 0 || r == rows - 1 ||
48 | c == 0 || c == cols - 1)
49 | cout << "*";
50 | else
51 | cout << " ";
52 | ++c;
53 | }
54 | }
55 | cout << endl;
56 | }
57 | return 0;
58 | }
--------------------------------------------------------------------------------
/Chapter 02/q03.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // say what standard-library names we use
5 | using std::cin; using std::endl;
6 | using std::cout; using std::string;
7 |
8 | int main()
9 | {
10 | // ask for the person's name
11 | cout << "Please enter your first name: ";
12 |
13 | // read the name
14 | string name;
15 | cin >> name;
16 |
17 | // build the message that we intend to write
18 | const string greeting = "Hello, " + name + "!";
19 |
20 | // the number of blanks surrounding the greeting
21 | int pad;
22 | cout << endl << "Please enter the amount of spacing between the frame and the greeting: ";
23 | cin >> pad;
24 |
25 | // the number of rows and columns to write
26 | const int rows = pad * 2 + 3;
27 | const string::size_type cols = greeting.size() + pad * 2 + 2;
28 |
29 | // write a blank line to separate the output from the input
30 | cout << endl;
31 |
32 | // write rows rows of output
33 | // invariant: we have written r rows so far
34 | for (int r = 0; r != rows; ++r) {
35 |
36 | string::size_type c = 0;
37 |
38 | // invariant: we have written c characters so far in the current row
39 | while (c != cols) {
40 |
41 | // is it time to write the greeting?
42 | if (r == pad + 1 && c == pad + 1) {
43 | cout << greeting;
44 | c += greeting.size();
45 | } else {
46 |
47 | // are we on the border?
48 | if (r == 0 || r == rows - 1 ||
49 | c == 0 || c == cols - 1)
50 | cout << "*";
51 | else
52 | cout << " ";
53 | ++c;
54 | }
55 | }
56 | cout << endl;
57 | }
58 | return 0;
59 | }
--------------------------------------------------------------------------------
/Chapter 02/q04.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // say what standard-library names we use
5 | using std::cin; using std::endl;
6 | using std::cout; using std::string;
7 |
8 | int main()
9 | {
10 | // ask for the person's name
11 | cout << "Please enter your first name: ";
12 |
13 | // read the name
14 | string name;
15 | cin >> name;
16 |
17 | // build the message that we intend to write
18 | const string greeting = "Hello, " + name + "!";
19 |
20 | // the number of blanks surrounding the greeting
21 | const int pad = 1;
22 |
23 | // the number of rows and columns to write
24 | const int rows = pad * 2 + 3;
25 | const string::size_type cols = greeting.size() + pad * 2 + 2;
26 |
27 | // write a blank line to separate the output from the input
28 | cout << endl;
29 |
30 | // write rows rows of output
31 | // invariant: we have written r rows so far
32 | for (int r = 0; r != rows; ++r) {
33 |
34 | string::size_type c = 0;
35 |
36 | // invariant: we have written c characters so far in the current row
37 | while (c != cols) {
38 |
39 | // is it time to write the greeting?
40 | if (r == pad + 1 && c == pad + 1) {
41 | cout << greeting;
42 | c += greeting.size();
43 | } else {
44 |
45 | // are we on the border?
46 | if (r == 0 || r == rows - 1 ||
47 | c == 0 || c == cols - 1) {
48 | cout << "*";
49 | ++c;
50 | } else if (r == pad + 1) {
51 | cout << string(pad, ' ');
52 | c += pad;
53 | }
54 | else {
55 | cout << string(cols - 2, ' ');
56 | c += cols - 2;
57 | }
58 | }
59 | }
60 | cout << endl;
61 | }
62 | return 0;
63 | }
--------------------------------------------------------------------------------
/Chapter 02/q05.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::cout;
5 | using std::cin;
6 | using std::endl;
7 | using std::string;
8 |
9 | int main()
10 | {
11 | int square_length = 3;
12 | // invariant: we have written r rows so far
13 | for (int r = 0; r < square_length; r++)
14 | cout << string(square_length, '*') << endl;
15 |
16 | cout << endl;
17 |
18 | int rectangle_width = 4;
19 | int rectangle_height = 3;
20 | // invariant: we have written r rows so far
21 | for (int r = 0; r < rectangle_height; r++)
22 | cout << string(rectangle_width, '*') << endl;
23 |
24 | cout << endl;
25 |
26 | int triangle_height = 3;
27 | // invariant: we have written r rows so far
28 | for (int r = 0; r < triangle_height; r++) {
29 | int length = r * 2 + 1;
30 | int spaces = (triangle_height * 2 - 1 - length) / 2;
31 | cout << string(spaces, ' ');
32 | cout << string(length, '*');
33 | cout << string(spaces, ' ') << endl;
34 | }
35 |
36 | return 0;
37 | }
--------------------------------------------------------------------------------
/Chapter 02/q07.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | // count down from 10 to -5.
6 | for (int i = 10; i > -6; --i)
7 | std::cout << i << std::endl;
8 |
9 | return 0;
10 | }
--------------------------------------------------------------------------------
/Chapter 02/q08.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | int product = 1;
6 | // get the product of the numbers in the range [1, 10).
7 | for (int i = 1; i < 10; i++)
8 | product *= i;
9 |
10 | std::cout << product << std::endl;
11 |
12 | return 0;
13 | }
--------------------------------------------------------------------------------
/Chapter 02/q09.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main()
4 | {
5 | // program that asks the user to enter two numbers and
6 | // tells the user which number is larger than the other.
7 | int num1, num2;
8 |
9 | std::cout << "Enter number 1: ";
10 | std::cin >> num1;
11 | std::cout << "Enter number 2: ";
12 | std::cin >> num2;
13 | std::cout << "The larger number is: ";
14 |
15 | if (num1 > num2)
16 | std::cout << num1;
17 | else
18 | std::cout << num2;
19 |
20 | return 0;
21 | }
--------------------------------------------------------------------------------
/Chapter 03/README.md:
--------------------------------------------------------------------------------
1 | ## Questions and Solutions
2 |
3 | ### Q0: Compile, execute and test the programs in this chapter.
4 | The programs in this chapter are compiled and tested. The programs can be found in the book.
5 |
6 | ### Q1: Suppose we wish to find the median of a collection of values. Assume that we have read some of the values so far, and that we have no idea how many values remain to be read. Prove that we cannot afford to discard any of the values that we have read. *Hint:* One proof strategy is to assume that we can discard a value, and then find values for the unread—and therefore unknown—part of our collection that would cause the median to be the value that we discarded.
7 | Let's say we have read the values 3, 4, and 7. It seems probable that we can discard the smallest or the largest value. Let's discard them. Now we have 4. Now, let's say we now read 1 and 2. Now we have 1, 2, and 4. It seems that the median should be 2, however, if we have not discarded any values, we would have 1, 2, 3, 4, and 7. The median would be 3, which we have discarded. That proves that we cannot afford to discard any value we have already read.
8 |
9 | ### Q2: Write a program to compute and print the quartiles (that is, the quarter of the numbers with the largest values, the next highest quarter, and so on) of a set of integers.
10 | The program can be found in [q02.cpp](./q02.cpp). It sorts the input numbers and prints each quartile. Note that if the number is not divisible by 4, the remainders are shared within the quartiles.
11 |
12 | ### Q3: Write a program to count how many times each distinct word appears in its input.
13 | The program can be found in [q03.cpp](./q03.cpp). It stores the input words and the number of appearances in separate `vector`s with the same indices for word and its respective count.
14 |
15 | ### Q4: Write a program to report the length of the longest and the shortest `string` in its input.
16 | The program can be found in [q04.cpp](./q04.cpp). It stores the lengths of the `string`s from the input into a `vector`, then sorts the `vector` to find the shortest and longest lengths. The shortest length is the first element, and the longest length is the last element of the vector.
17 |
18 | ### Q5: Write a program that will keep track of grades for several students at once. The program could keep two `vector`s in sync: The first should hold the students' names, and the second the final grades that can be computed as input is read. For now, you should assume a fixed number of homework grades. We'll see in §4.1.3/56 how to handle a variable number of grades intermixed with student names.
19 | The solution can be found in [q05.cpp](./q05.cpp). The program first reads the student's name, followed by final grade, midterm grade, and homework grades. It stores the student's name in a `vector`. Then, it calculates the student's final grade and stores it in another vector, with the same index as the student name `vector`.
20 |
21 | ### Q6: The average-grade computation in §3.1/36 might divide by zero if the student didn't enter any grades. Division by zero is undefined in C++, which means the implementation is permitted to do anything it likes. What does your C++ implementation do in this case? Rewrite the program so that its behavior does not depend on how the implementation treats division by zero.
22 | My implementation, g++, outputs nan when no homework grades are entered. In [q06.cpp](./q06.cpp), the program is rewritten so that it sets the homework grade as zero if no grade is entered.
--------------------------------------------------------------------------------
/Chapter 03/q02.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::cout;
6 | using std::cin;
7 | using std::endl;
8 | using std::vector;
9 | using std::sort;
10 |
11 | int main()
12 | {
13 | vector numbers;
14 | int n;
15 |
16 | // ask for number input
17 | cout << "Please enter the numbers, followed by end-of-file." << endl;
18 |
19 | // invariant: numbers contains numbers read so far
20 | while (cin >> n)
21 | numbers.push_back(n);
22 |
23 | // sort the numbers
24 | sort(numbers.begin(), numbers.end());
25 |
26 | // get the properties of the vector
27 | typedef vector::size_type vec_sz;
28 | vec_sz count = numbers.size();
29 | int quartile_size = count / 4;
30 | int quartile_remainder = count % 4;
31 |
32 | // handle not enough numbers condition
33 | if (count < 4) {
34 | cout << "You must enter at least 4 numbers." << endl;
35 | return(1);
36 | }
37 |
38 | // print the quartiles
39 | for (vec_sz i = count; i-- > 0; ) {
40 | if (i == count - 1)
41 | cout << "First quartile: ";
42 | else if (i == 3 * quartile_size - 1 + quartile_remainder)
43 | cout << endl << "Second quartile: ";
44 | else if (i == 2 * quartile_size - 1 + (quartile_remainder > 1 ?
45 | quartile_remainder - 1 : 0))
46 | cout << endl << "Third quartile: ";
47 | else if (i == quartile_size - 1 + (quartile_remainder == 3 ? 1 : 0))
48 | cout << endl << "Fourth quartile: ";
49 |
50 | cout << numbers[i] << " ";
51 | }
52 |
53 | return 0;
54 | }
--------------------------------------------------------------------------------
/Chapter 03/q03.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::cout;
6 | using std::endl;
7 | using std::cin;
8 | using std::string;
9 | using std::vector;
10 |
11 | int main()
12 | {
13 | // ask for string input
14 | cout << "Enter a sentence, followed by end-of-file: " << endl;
15 |
16 | vector words;
17 | vector counts;
18 | typedef vector::size_type vec_sz;
19 | string word;
20 | vec_sz size;
21 |
22 | // read the sentence
23 | // invariant: words contains the words read so far
24 | while (cin >> word) {
25 | int found_index = -1;
26 | size = words.size();
27 | // search the vector for word
28 | for (vec_sz i = 0; i < size; i++)
29 | if (words[i] == word)
30 | found_index = i;
31 |
32 | // if word exists, increment its count
33 | if (found_index > 0)
34 | ++counts[found_index];
35 | else {
36 | words.push_back(word);
37 | counts.push_back(1);
38 | }
39 | }
40 |
41 | // write the results
42 | size = words.size();
43 | for (vec_sz i = 0; i < size; ++i)
44 | cout << "Word: " << words[i] << ", Count: " << counts[i] << endl;
45 |
46 | return 0;
47 | }
--------------------------------------------------------------------------------
/Chapter 03/q04.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::cout;
7 | using std::endl;
8 | using std::cin;
9 | using std::string;
10 | using std::vector;
11 | using std::sort;
12 |
13 | int main()
14 | {
15 | // ask for string input
16 | cout << "Enter a sentence, followed by end-of-file: " << endl;
17 |
18 | typedef vector::size_type vec_sz;
19 | vector sizes;
20 | string word;
21 |
22 | // invariant: sizes contains the length of the words read so far
23 | while (cin >> word)
24 | sizes.push_back(word.size());
25 |
26 | // sort the sizes vector
27 | sort(sizes.begin(), sizes.end());
28 |
29 | // write the results
30 | cout << "Shortest length: " << sizes[0] << endl;
31 | cout << "Longest length: " << sizes[sizes.size() - 1] << endl;
32 | }
--------------------------------------------------------------------------------
/Chapter 03/q05.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::cout;
6 | using std::endl;
7 | using std::cin;
8 | using std::string;
9 | using std::vector;
10 |
11 | int main()
12 | {
13 | vector students;
14 | vector grades;
15 | string student;
16 |
17 | typedef vector::size_type vec_sz;
18 |
19 | // set homework amount
20 | const int hw_count = 3;
21 |
22 | // ask for user input
23 | cout << "Please enter student name, followed by midterm grade, "
24 | "final grade, and " << hw_count << " homework grades."
25 | " Send end-of-file to finish submitting." << endl;
26 |
27 | // invariant:
28 | // students contains student names read so far, and
29 | // grades contains the final grades of the students
30 | while (cin >> student) {
31 | students.push_back(student);
32 | double midterm, final;
33 | double hw_sum = 0.0;
34 |
35 | cin >> midterm >> final;
36 |
37 | for (int i = 0; i < hw_count; ++i) {
38 | double grade;
39 | cin >> grade;
40 | hw_sum += grade;
41 | };
42 |
43 | grades.push_back(0.2 * midterm + 0.4 * final + 0.4 * hw_sum / hw_count);
44 | }
45 |
46 | // write the results
47 | for (vec_sz i = 0; i < students.size(); ++i)
48 | cout << "Student " << students[i] << "'s Final Grade: " <<
49 | grades[i] << "." << endl;
50 |
51 | return 0;
52 | }
--------------------------------------------------------------------------------
/Chapter 03/q06.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::cin; using std::setprecision;
7 | using std::cout; using std::string;
8 | using std::endl; using std::streamsize;
9 |
10 | int main()
11 | {
12 | // ask for and read the student's name
13 | cout << "Please enter your first name: ";
14 | string name;
15 | cin >> name;
16 | cout << "Hello, " << name << "!" << endl;
17 |
18 | // ask for and read the midterm and final grades
19 | cout << "Please enter your midterm and final exam grades: ";
20 | double midterm, final;
21 | cin >> midterm >> final;
22 |
23 | // ask for the homework grades
24 | cout << "Enter all your homework grades, "
25 | "followed by end-of-file: ";
26 |
27 | // the number and sum of grades read so far
28 | int count = 0;
29 | double sum = 0;
30 |
31 | // a variable into which to read
32 | double x;
33 |
34 | // invariant:
35 | // we have read count grades so far, and
36 | // sum is the sum of the first count grades
37 | while (cin >> x) {
38 | ++count;
39 | sum += x;
40 | }
41 |
42 | // set homework variable, handling the division by zero condition
43 | double homework = count == 0 ? 0 : sum / count;
44 |
45 | // write the result
46 | streamsize prec = cout.precision();
47 | cout << "Your final grade is " << setprecision(3)
48 | << 0.2 * midterm + 0.4 * final + 0.4 * homework
49 | << setprecision(prec) << endl;
50 |
51 | return 0;
52 | }
--------------------------------------------------------------------------------
/Chapter 04/Student_info.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "grade.h"
6 | #include "Student_info.h"
7 |
8 | using std::cout;
9 | using std::vector;
10 | using std::istream;
11 | using std::domain_error;
12 | using std::sort;
13 |
14 | // code is taken from §4.4/69
15 | bool compare(const Student_info& x, const Student_info& y)
16 | {
17 | return x.name < y.name;
18 | }
19 |
20 | istream& read(istream& is, Student_info& s)
21 | {
22 | double midterm, final;
23 | vector homework;
24 | // read and store the student's name and final grade
25 | is >> s.name >> midterm >> final;
26 |
27 | // handle end-of-file
28 | if (is) {
29 | read_hw(is, homework);
30 | // save only the final grade
31 | s.final_grade = grade(midterm, final, homework);
32 | }
33 |
34 | return is;
35 | }
36 |
37 | // code is taken from §4.1.3/57
38 | istream& read_hw(istream& in, vector& hw)
39 | {
40 | if (in) {
41 | // get rid of previous contetns
42 | hw.clear();
43 |
44 | // read homework grades
45 | double x;
46 | while (in >> x)
47 | hw.push_back(x);
48 |
49 | // clear the stream so that input will work for the next student
50 | in.clear();
51 | }
52 | return in;
53 | }
--------------------------------------------------------------------------------
/Chapter 04/Student_info.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_Student_info
2 | #define Guard_Student_info
3 |
4 | #include
5 | #include
6 |
7 | struct Student_info {
8 | std::string name;
9 | double final_grade;
10 | };
11 |
12 | bool compare(const Student_info&, const Student_info&);
13 | std::istream& read(std::istream&, Student_info&);
14 | std::istream& read_hw(std::istream&, std::vector&);
15 | #endif
--------------------------------------------------------------------------------
/Chapter 04/grade.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "grade.h"
4 | #include "median.h"
5 |
6 | using std::domain_error; using std::vector;
7 |
8 | // code taken from §4.1/52
9 | // compute a student's overall grade from midterm and final exam grades and homework grade
10 | double grade(double midterm, double final, double homework)
11 | {
12 | return 0.2 * midterm + 0.4 * final + 0.4 * homework;
13 | }
14 |
15 | // code taken from §4.1.2/54
16 | // compute a student's overall grade from midterm and final exam grades
17 | // and vector of homework grades.
18 | // this function does not copy its argument, because median does so for us.
19 | double grade(double midterm, double final, const vector& hw)
20 | {
21 | if (hw.size() == 0)
22 | throw domain_error("student has done no homework");
23 | return grade(midterm, final, median(hw));
24 | }
--------------------------------------------------------------------------------
/Chapter 04/grade.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_grade_h
2 | #define GUARD_grade_h
3 |
4 | #include
5 |
6 | double grade(double, double, double);
7 | double grade(double, double, const std::vector&);
8 | #endif
--------------------------------------------------------------------------------
/Chapter 04/median.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "median.h"
5 |
6 | using std::domain_error;
7 | using std::vector;
8 | using std::sort;
9 |
10 | // code is taken from §4.1.1/53
11 | // compute the median of a vector
12 | // note that calling this function copies the entire argument vector
13 | double median(vector vec)
14 | {
15 | typedef vector::size_type vec_sz;
16 |
17 | vec_sz size = vec.size();
18 | if (size == 0)
19 | throw domain_error("median of an empty vector");
20 |
21 | sort(vec.begin(), vec.end());
22 |
23 | vec_sz mid = size/2;
24 |
25 | return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
26 | }
27 |
--------------------------------------------------------------------------------
/Chapter 04/median.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_median_h
2 | #define GUARD_median_h
3 |
4 | #include
5 |
6 | double median(std::vector);
7 | #endif
--------------------------------------------------------------------------------
/Chapter 04/q02.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::cout;
5 | using std::endl;
6 | using std::setw;
7 |
8 | int main()
9 | {
10 | for (int i = 1; i <= 100; i++)
11 | cout << setw(3) << i << setw(6) << i * i << endl;
12 |
13 | return 0;
14 | }
--------------------------------------------------------------------------------
/Chapter 04/q03.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::cout;
5 | using std::endl;
6 | using std::setw;
7 |
8 | // function that returns the length of a number
9 | // when converted to a string
10 | int get_length(int number)
11 | {
12 | int length = 1;
13 | while (number / 10 > 0) {
14 | number /= 10;
15 | ++length;
16 | }
17 |
18 | return length;
19 | }
20 |
21 | int main()
22 | {
23 | const int max_number = 999;
24 |
25 | int max_len = get_length(max_number);
26 | int max_sq = get_length(max_number * max_number);
27 |
28 | for (int i = 1; i <= max_number; ++i)
29 | cout << setw(max_len) << i << setw(max_sq + 1) << i * i << endl;
30 |
31 | return 0;
32 | }
--------------------------------------------------------------------------------
/Chapter 04/q04.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | using std::cout;
5 | using std::endl;
6 | using std::setw;
7 | using std::streamsize;
8 | using std::setprecision;
9 | using std::fixed;
10 |
11 | // function that returns the length of a number
12 | // when converted to a string
13 | int get_length(double number, const streamsize& decimal_points)
14 | {
15 | int length = 1;
16 | while (number / 10 > 1.0) {
17 | number /= 10;
18 | ++length;
19 | }
20 |
21 | return length + decimal_points + 1;
22 | }
23 |
24 | int main()
25 | {
26 | const double max_number = 1000.0;
27 | const streamsize decimal_points = 2;
28 |
29 | int max_len = get_length(max_number, decimal_points);
30 | int max_sq = get_length(max_number * max_number, decimal_points);
31 |
32 | for (double i = 1.0; i < max_number; ++i) {
33 | streamsize prec = cout.precision();
34 | cout << fixed << setprecision(decimal_points) << setw(max_len) << i
35 | << setw(max_sq + 1) << i * i << setprecision(prec) << endl;
36 | }
37 |
38 | return 0;
39 | }
--------------------------------------------------------------------------------
/Chapter 04/q05-1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "read_words.h"
5 |
6 | // program that counts the number of words in the input
7 |
8 | using std::cin;
9 | using std::cout;
10 | using std::endl;
11 | using std::vector;
12 | using std::string;
13 |
14 | int main()
15 | {
16 | vector words;
17 | vector::size_type count = 0;
18 |
19 | // ask for string input
20 | cout << "Enter a sentence, followed by end-of-file: " << endl;
21 |
22 | // using the created function
23 | read_words(cin, words);
24 |
25 | // write the result
26 | cout << "There are " << words.size() << " words in the input." << endl;
27 |
28 | return 0;
29 | }
--------------------------------------------------------------------------------
/Chapter 04/q05-2.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "read_words.h"
6 |
7 | // program that counts how many times each word occured
8 |
9 | using std::cin;
10 | using std::cout;
11 | using std::endl;
12 | using std::vector;
13 | using std::string;
14 | using std::sort;
15 |
16 | typedef vector::size_type vec_sz;
17 |
18 | int main()
19 | {
20 | vector words;
21 |
22 | // ask for string input
23 | cout << "Enter a sentence, followed by end-of-file: " << endl;
24 |
25 | // using the created function
26 | read_words(cin, words);
27 |
28 | // sort the vector to group same words
29 | sort(words.begin(), words.end());
30 |
31 | // write the results
32 | string word = words[0];
33 | vec_sz count = 0;
34 | for (vec_sz i = 0; i < words.size(); ++i)
35 | if (word != words[i]) {
36 | cout << "Word " << word << " appeared "
37 | << ++count << " time" << (count > 1 ? "s." : ".") << endl;
38 | word = words[i];
39 | count = 0;
40 | } else
41 | ++count;
42 |
43 | return 0;
44 | }
--------------------------------------------------------------------------------
/Chapter 04/q06.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "Student_info.h"
9 |
10 | using std::cin; using std::setprecision;
11 | using std::cout; using std::sort;
12 | using std::domain_error; using std::streamsize;
13 | using std::endl; using std::string;
14 | using std::max; using std::vector;
15 |
16 | int main()
17 | {
18 | vector students;
19 | Student_info record;
20 | string::size_type maxlen=0; // the length of the longest name
21 |
22 | // read and store all the students' data
23 | // invariant: students contains all the student records read so far
24 | // maxlen contains the length of the longest name in students
25 | while (read(cin, record)) {
26 | // find the length of longest name
27 | maxlen = max(maxlen, record.name.size());
28 | students.push_back(record);
29 | }
30 |
31 | // alphabetize the student records
32 | sort(students.begin(), students.end(), compare);
33 |
34 | // write the names and grades
35 | for (vector::size_type i = 0;
36 | i != students.size(); ++i) {
37 |
38 | // write the name, padded on the right to maxlen + 1 characters
39 | cout << students[i].name
40 | << string(maxlen + 1 - students[i].name.size(), ' ');
41 |
42 | // write the grades
43 | try {
44 | streamsize prec = cout.precision();
45 | cout << setprecision(3) << students[i].final_grade
46 | << setprecision(prec) << endl;
47 | } catch (domain_error e) {
48 | cout << e.what();
49 | }
50 | cout << endl;
51 | }
52 | return 0;
53 | }
--------------------------------------------------------------------------------
/Chapter 04/q07.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::cout;
6 | using std::endl;
7 | using std::cin;
8 | using std::string;
9 | using std::vector;
10 |
11 | int main()
12 | {
13 | vector doubles;
14 |
15 | // ask the for double input
16 | cout << "Enter doubles, followed by end-of-file: " << endl;
17 |
18 | double d;
19 | while (cin >> d)
20 | doubles.push_back(d);
21 |
22 | // find the average of the numbers stored in the vector
23 | double total = 0;
24 | double count = doubles.size();
25 | for (vector::size_type i = 0; i < count; ++i)
26 | total += doubles[i];
27 |
28 | cout << "The average is: " << total / count << endl;
29 | }
--------------------------------------------------------------------------------
/Chapter 04/read_words.cpp:
--------------------------------------------------------------------------------
1 | #include "read_words.h"
2 |
3 | using std::istream;
4 | using std::vector;
5 | using std::string;
6 |
7 | istream& read_words(istream& is, vector& words)
8 | {
9 | if (is) {
10 | string word;
11 |
12 | // clear the vector
13 | words.clear();
14 |
15 | // read and store the words
16 | while (is >> word)
17 | words.push_back(word);
18 |
19 | // reset the error state
20 | is.clear();
21 | }
22 |
23 | return is;
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Chapter 04/read_words.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_read_words_h
2 | #define GUARD_read_words_h
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | std::istream& read_words(std::istream& is, std::vector& vec);
9 | #endif
--------------------------------------------------------------------------------
/Chapter 05/10.txt:
--------------------------------------------------------------------------------
1 | YNEFQ 29 32 33 64 30
2 | SHZ 71 64 64 23 87
3 | JSU 20 86 50 38 62
4 | PLLVK 65 92 26 65 64
5 | XZC 24 92 40 59 33
6 | MMYDPWW 47 63 28 72 48
7 | YTBJWXM 54 58 24 22 38
8 | RTDKZL 97 45 61 60 28
9 | WAU 35 71 47 70 73
10 | QOPX 76 98 37 50 98
--------------------------------------------------------------------------------
/Chapter 05/Rotation.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_Rotation
2 | #define GUARD_Rotation
3 |
4 | #include
5 | #include
6 |
7 | struct Rotation {
8 | std::vector words;
9 | std::vector::size_type start;
10 | };
11 |
12 | std::vector get_rotations(const std::string&);
13 | std::vector sort_rotations(std::vector&);
14 | std::string format_rotation(Rotation&, std::string::size_type);
15 | std::string::size_type first_width(const Rotation&);
16 | std::string::size_type first_width(const std::vector&);
17 | bool compare(const Rotation&, const Rotation&);
18 | #endif
--------------------------------------------------------------------------------
/Chapter 05/frame.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "frame.h"
4 |
5 | using std::vector;
6 | using std::string;
7 | using std::max;
8 |
9 | // code is taken from §5.8.1/92
10 | string::size_type width(const vector& v)
11 | {
12 | string::size_type maxlen = 0;
13 | for (vector::size_type i = 0; i != v.size(); ++i)
14 | maxlen = max(maxlen, v[i].size());
15 | return maxlen;
16 | }
17 |
18 | // code is taken from §5.8.1/93
19 | vector frame(const vector& v)
20 | {
21 | vector ret;
22 | string::size_type maxlen = width(v);
23 | string border(maxlen + 4, '*');
24 |
25 | // write the top border
26 | ret.push_back(border);
27 |
28 | // write each interior row, bordered by an asterisk and a space
29 | for (vector::size_type i = 0; i != v.size(); ++i) {
30 | ret.push_back("* " + v[i] +
31 | string(maxlen - v[i].size(), ' ') + " *");
32 | }
33 |
34 | // write the bottom border
35 | ret.push_back(border);
36 | return ret;
37 | }
--------------------------------------------------------------------------------
/Chapter 05/frame.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_frame_h
2 | #define GUARD_frame_h
3 |
4 | #include
5 | #include
6 |
7 | std::string::size_type width(const std::vector& v);
8 | std::vector frame(const std::vector& v);
9 | #endif
--------------------------------------------------------------------------------
/Chapter 05/q01.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "Rotation.h"
7 |
8 | using std::string;
9 | using std::cout;
10 | using std::cin;
11 | using std::endl;
12 | using std::vector;
13 | using std::list;
14 | using std::istream;
15 | using std::sort;
16 |
17 | // read every line in an input stream until end-of-file
18 | list read_each_line(istream& in)
19 | {
20 | list lines;
21 | string s;
22 | // read each line and add them to a vector
23 | while (getline(in, s))
24 | lines.push_back(s);
25 |
26 | return lines;
27 | }
28 |
29 | int main()
30 | {
31 | // using list for optimization, as we will only
32 | // iterate over read lines
33 | list lines = read_each_line(cin);
34 |
35 | // Save the rotations for each vector
36 | vector rotations;
37 |
38 | // loop for each line
39 | for (list::const_iterator it = lines.begin();
40 | it != lines.end(); ++it) {
41 | // save each line's rotations and concatenate them
42 | // to the rotations vector
43 | vector lr = get_rotations(*it);
44 | rotations.insert(rotations.end(), lr.begin(), lr.end());
45 | }
46 |
47 | // sort and format the permutations
48 | sort(rotations.begin(), rotations.end(), compare);
49 |
50 | // write the results
51 | string::size_type max_width = first_width(rotations);
52 | for (vector::iterator it = rotations.begin();
53 | it != rotations.end(); ++it)
54 | cout << format_rotation(*it, max_width) << endl;
55 |
56 | return 0;
57 | }
--------------------------------------------------------------------------------
/Chapter 05/q02-1.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | // ctime is used for code runtime estimation
4 | #include
5 | // include the simplified version of Student_info
6 | #include "../Chapter 04/Student_info.h"
7 |
8 | using std::cin;
9 | using std::cout;
10 | using std::endl;
11 | using std::vector;
12 |
13 | vector extract_fails(vector& students)
14 | {
15 | vector fails;
16 | vector::iterator it = students.begin();
17 | while (it != students.end()) {
18 | // we can access only the final grade from simplified version
19 | if (it->final_grade < 60) {
20 | fails.push_back(*it);
21 | it = students.erase(it);
22 | } else
23 | ++it;
24 | }
25 |
26 | return fails;
27 | }
28 |
29 | int main()
30 | {
31 | vector students;
32 | Student_info student;
33 |
34 | // read all student data
35 | while (read(cin, student))
36 | students.push_back(student);
37 |
38 | // save the original size
39 | vector::size_type count = students.size();
40 |
41 | double begin = clock();
42 | vector fails = extract_fails(students);
43 | double end = clock();
44 |
45 | cout << "Extracting fails for " << count << " students took "
46 | << (end - begin) / CLOCKS_PER_SEC << " seconds." << endl;
47 |
48 | return 0;
49 | }
--------------------------------------------------------------------------------
/Chapter 05/q02-2.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | // ctime is used for code runtime estimation
4 | #include
5 | // include the simplified version of Student_info
6 | #include "../Chapter 04/Student_info.h"
7 |
8 | using std::cin;
9 | using std::cout;
10 | using std::endl;
11 | using std::list;
12 |
13 | list extract_fails(list& students)
14 | {
15 | list fails;
16 | list::iterator it = students.begin();
17 | while (it != students.end()) {
18 | // we can access only the final grade from simplified version
19 | if (it->final_grade < 60) {
20 | fails.push_back(*it);
21 | it = students.erase(it);
22 | } else
23 | ++it;
24 | }
25 |
26 | return fails;
27 | }
28 |
29 | int main()
30 | {
31 | list students;
32 | Student_info student;
33 |
34 | // read all student data
35 | while (read(cin, student))
36 | students.push_back(student);
37 |
38 | // save the original size
39 | list::size_type count = students.size();
40 |
41 | double begin = clock();
42 | list fails = extract_fails(students);
43 | double end = clock();
44 |
45 | cout << "Extracting fails for " << count << " students took "
46 | << (end - begin) / CLOCKS_PER_SEC << " seconds." << endl;
47 |
48 | return 0;
49 | }
--------------------------------------------------------------------------------
/Chapter 05/q03.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | // #include
4 | // ctime is used for code runtime estimation
5 | #include
6 | // include the simplified version of Student_info
7 | #include "../Chapter 04/Student_info.h"
8 |
9 | using std::cin;
10 | using std::cout;
11 | using std::endl;
12 | using std::clock_t;
13 |
14 | typedef std::vector student_container;
15 | // typedef std::list student_container;
16 |
17 | student_container extract_fails(student_container& students)
18 | {
19 | student_container fails;
20 | student_container::iterator it = students.begin();
21 | while (it != students.end()) {
22 | // we can access only the final grade from simplified version
23 | if (it->final_grade < 60) {
24 | fails.push_back(*it);
25 | it = students.erase(it);
26 | } else
27 | ++it;
28 | }
29 |
30 | return fails;
31 | }
32 |
33 | int main()
34 | {
35 | student_container students;
36 | Student_info student;
37 |
38 | // read all student data
39 | while (read(cin, student))
40 | students.push_back(student);
41 |
42 | // save the original size
43 | student_container::size_type count = students.size();
44 |
45 | double begin = clock();
46 | student_container fails = extract_fails(students);
47 | double end = clock();
48 |
49 | cout << "Extracting fails for " << count << " students took "
50 | << (end - begin) / CLOCKS_PER_SEC << " seconds." << endl;
51 |
52 | return 0;
53 | }
--------------------------------------------------------------------------------
/Chapter 05/q05.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "split.h"
5 |
6 | using std::cout;
7 | using std::endl;
8 | using std::string;
9 | using std::vector;
10 |
11 | typedef string::size_type str_sz;
12 | typedef vector::size_type vec_sz;
13 |
14 | vector center(const vector& picture)
15 | {
16 | vector centered_picture = picture;
17 | // the picture is assumed to be rectangular
18 | str_sz width = centered_picture[0].size() - 2;
19 | // iterate over the picture
20 | for (vector::iterator it = centered_picture.begin();
21 | it != centered_picture.end(); ++it)
22 | // skip first and last lines
23 | if (it != centered_picture.begin() && it != centered_picture.end() - 1) {
24 | // remove * characters
25 | (*it)[0] = ' ';
26 | (*it)[width + 1] = ' ';
27 | vector words = split(*it);
28 | string unpadded_line = "";
29 | // get each word to find the unpadded line
30 | for (vector::const_iterator jt = words.begin();
31 | jt != words.end(); ++jt) {
32 | // add the word to unpadded line
33 | unpadded_line += *jt;
34 | // add one space if word is not the last one
35 | if (jt + 1 != words.end())
36 | unpadded_line += " ";
37 | }
38 | // get the unpadded line width
39 | str_sz unpadded_line_width = unpadded_line.size();
40 | // get the size of the paddings
41 | str_sz left_padding = (width - unpadded_line_width) / 2;
42 | str_sz right_padding = width - unpadded_line_width - left_padding;
43 | // set centered line
44 | *it = "*" + string(left_padding, ' ') +
45 | unpadded_line + string(right_padding, ' ') + "*";
46 | }
47 |
48 | return centered_picture;
49 | }
50 |
51 | int main()
52 | {
53 | vector picture;
54 | // create a picture
55 | picture.push_back("*************");
56 | picture.push_back("* hello *");
57 | picture.push_back("* my name *");
58 | picture.push_back("* is Altug! *");
59 | picture.push_back("*************");
60 |
61 | vector centered_picture = center(picture);
62 |
63 | // picture and centered_picture have the same size
64 | vec_sz size = picture.size();
65 | for (vec_sz i = 0; i < size; ++i) {
66 | cout << picture[i] << " ";
67 | if (i == size / 2)
68 | cout << "=>";
69 | else
70 | cout << " ";
71 | cout << " " << centered_picture[i] << endl;
72 | }
73 |
74 | return 0;
75 | }
--------------------------------------------------------------------------------
/Chapter 05/q06.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "../Chapter 04/Student_info.h"
4 | // ctime is used for code runtime estimation
5 | #include
6 |
7 | using std::cout;
8 | using std::cin;
9 | using std::endl;
10 | using std::vector;
11 |
12 | typedef vector::size_type vec_std_sz;
13 |
14 | // code is taken from §5.1.1/77, modified to fit the simplified
15 | // Student_info structure.
16 | vector extract_fails(vector& students)
17 | {
18 | vector fail;
19 | vec_std_sz i = 0;
20 |
21 | // invariant: elements [0, i) of students represent passing grades
22 | while (i != students.size()) {
23 | if (students[i].final_grade < 60) {
24 | fail.push_back(students[i]);
25 | students.erase(students.begin() + i);
26 | } else
27 | ++i;
28 | }
29 | return fail;
30 | }
31 |
32 | vector resizing_extract_fails(vector& students)
33 | {
34 | vector fail;
35 | vec_std_sz original_size = students.size();
36 |
37 | for (vec_std_sz i = 0; i != students.size(); ++i)
38 | if (students[i].final_grade < 60)
39 | fail.push_back(students[i]);
40 | else
41 | students.insert(students.begin(), students[i++]);
42 |
43 | students.resize(original_size - fail.size());
44 | return fail;
45 | }
46 |
47 | int main()
48 | {
49 | vector students;
50 | Student_info student;
51 | // read all student data
52 | while (read(cin, student))
53 | students.push_back(student);
54 |
55 | // save the original size
56 | vec_std_sz count = students.size();
57 |
58 | // create a copy to measure both functions
59 | vector students_copy(students);
60 |
61 | // measure time for the original function
62 | double begin = clock();
63 | extract_fails(students);
64 | double time_original = clock() - begin;
65 |
66 | // measure time for the modified function
67 | begin = clock();
68 | resizing_extract_fails(students_copy);
69 | double time_modified = clock() - begin;
70 |
71 | // write the results
72 | cout << "Original function took " << time_original / CLOCKS_PER_SEC
73 | << " seconds and the modified function took " << time_modified /
74 | CLOCKS_PER_SEC << " seconds for " << count << " students." << endl;
75 |
76 | return 0;
77 | }
--------------------------------------------------------------------------------
/Chapter 05/q07.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "frame.h"
5 |
6 | using std::cout;
7 | using std::endl;
8 | using std::vector;
9 | using std::string;
10 |
11 | int main()
12 | {
13 | vector v;
14 | frame(v);
15 |
16 | // write the frame
17 | for (vector::const_iterator it = v.begin();
18 | it != v.end(); ++it)
19 | cout << *it << endl;
20 |
21 | return 0;
22 | }
--------------------------------------------------------------------------------
/Chapter 05/q08.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::string;
7 | using std::max;
8 | using std::cout;
9 | using std::endl;
10 |
11 | // code taken from §5.8.1/92
12 | string::size_type width(const vector& v)
13 | {
14 | string::size_type maxlen = 0;
15 | for (vector::size_type i = 0; i != v.size(); ++i)
16 | maxlen = max(maxlen, v[i].size());
17 | return maxlen;
18 | }
19 |
20 | // code taken from §5.8.3/95, modified to define s
21 | // outside the scope of the while
22 | vector hcat(const vector& left, const vector& right)
23 | {
24 | vector ret;
25 |
26 | // add 1 to leave a space between pictures
27 | string::size_type width1 = width(left) + 1;
28 |
29 | // indices to look at elements from left and right respectively
30 | vector::size_type i = 0, j = 0;
31 |
32 | // define s here
33 | string s;
34 |
35 | while (i != left.size() || j != right.size()) {
36 | // copy a row from the left-hand side, if there is one
37 | if (i != left.size())
38 | s = left[i++];
39 |
40 | // pad to full width
41 | s += string(width1 - s.size(), ' ');
42 |
43 | // copy a row from the right-hand side, if there is one
44 | if (j != right.size())
45 | s += right[j++];
46 |
47 | // add s to the picture we're creating
48 | ret.push_back(s);
49 | }
50 | return ret;
51 | }
52 |
53 | int main()
54 | {
55 | vector picture;
56 | // create a picture
57 | picture.push_back("*************");
58 | picture.push_back("* hello *");
59 | picture.push_back("* my name *");
60 | picture.push_back("* is Altug! *");
61 | picture.push_back("*************");
62 |
63 | vector another_picture;
64 | // create another picture to horizontally concatenate
65 | picture.push_back("***************");
66 | picture.push_back("* I am *");
67 | picture.push_back("* programming *");
68 | picture.push_back("* in C++! *");
69 | picture.push_back("***************");
70 |
71 | // concatenate
72 | vector result = hcat(picture, another_picture);
73 | // the code throws an exception if we switch the parameters
74 | // vector result = hcat(picture, another_picture);
75 |
76 | for (vector::const_iterator line = result.begin();
77 | line != result.end(); ++line)
78 | cout << *line << endl;
79 |
80 | return 0;
81 | }
--------------------------------------------------------------------------------
/Chapter 05/q09.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::cout;
7 | using std::cin;
8 | using std::endl;
9 | using std::list;
10 | using std::string;
11 | using std::isupper;
12 |
13 | bool is_all_lower(string word)
14 | {
15 | for (string::const_iterator it = word.begin();
16 | it != word.end(); ++it)
17 | if (isupper(*it))
18 | return false;
19 | return true;
20 | }
21 |
22 | int main()
23 | {
24 | list upper;
25 | list lower;
26 | string word;
27 | // read all input
28 | while (cin >> word)
29 | if (is_all_lower(word))
30 | lower.push_back(word);
31 | else
32 | upper.push_back(word);
33 |
34 | // write all lowercase words
35 | for (list::const_iterator it = lower.begin();
36 | it != lower.end(); ++it)
37 | cout << *it << " ";
38 |
39 | // write words that contain uppercase
40 | for (list::const_iterator it = upper.begin();
41 | it != upper.end(); ++it)
42 | cout << *it << " ";
43 | }
--------------------------------------------------------------------------------
/Chapter 05/q10.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | using std::vector;
7 | using std::string;
8 | using std::cout;
9 | using std::cin;
10 | using std::endl;
11 | using std::domain_error;
12 |
13 | bool is_palindrome(string s)
14 | {
15 | string::size_type length = s.size();
16 | // create a string with the same size as s
17 | string ret = s;
18 | for (string::size_type i = 0; i < length; ++i)
19 | ret[i] = s[length - i - 1];
20 |
21 | return s == ret;
22 | }
23 |
24 | int main()
25 | {
26 | vector palindromes;
27 | string word;
28 | string longest_word;
29 | string::size_type max_length = 0;
30 | // read all input
31 | while (cin >> word)
32 | if (is_palindrome(word)) {
33 | palindromes.push_back(word);
34 | string::size_type size = word.size();
35 | // update the longest word
36 | if (size > max_length) {
37 | longest_word = word;
38 | max_length = size;
39 | }
40 | }
41 |
42 | // check if there are any palindromes
43 | if (palindromes.size() == 0) {
44 | throw domain_error("no palindromes found");
45 | }
46 |
47 | // write the first palindrome
48 | vector::const_iterator it = palindromes.begin();
49 | cout << "The palindrome(s) are: " << *it;
50 |
51 | ++it;
52 | // write the rest of the palindromes, if any
53 | while (it != palindromes.end()) {
54 | cout << ", " << *it;
55 | ++it;
56 | }
57 | // write the result
58 | cout << endl << endl << "The longest palindrome is \"" << longest_word
59 | << "\" with " << max_length << " letters." << endl;
60 |
61 | return 0;
62 | }
--------------------------------------------------------------------------------
/Chapter 05/q11.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | using std::vector;
6 | using std::string;
7 | using std::cout;
8 | using std::cin;
9 | using std::endl;
10 |
11 | bool is_ascender_or_descender(char c)
12 | {
13 | return c == 'b' || c == 'd' || c == 'f' || c == 'h' ||
14 | c == 'k' || c == 'l' || c == 'g' || c == 'j' ||
15 | c == 'p' || c == 'q' || c == 'y';
16 | }
17 |
18 | bool has_ascender_or_descender(string s)
19 | {
20 | // search all characters
21 | for (string::const_iterator it = s.begin();
22 | it != s.end(); ++it)
23 | if (is_ascender_or_descender(*it))
24 | return true;
25 |
26 | return false;
27 | }
28 |
29 | int main()
30 | {
31 | vector words;
32 | string word;
33 | string longest_word;
34 | string::size_type max_length = 0;
35 | // read all input
36 | while (cin >> word)
37 | if (has_ascender_or_descender(word))
38 | words.push_back(word);
39 | else {
40 | string::size_type size = word.size();
41 | // update the longest word
42 | if (size > max_length) {
43 | longest_word = word;
44 | max_length = size;
45 | }
46 | }
47 |
48 | // write the first word
49 | vector::const_iterator it = words.begin();
50 | cout << "The word(s) that have ascenders or descenders are: "
51 | << *it;
52 |
53 | ++it;
54 | // write the rest of the words, if any
55 | while (it != words.end()) {
56 | cout << ", " << *it;
57 | ++it;
58 | }
59 |
60 | // write the result
61 | cout << endl << "The longest word that does not have ascenders or "
62 | "descenders is \"" << longest_word << "\" with " << max_length
63 | << " letters." << endl;
64 |
65 | return 0;
66 | }
--------------------------------------------------------------------------------
/Chapter 05/split.cpp:
--------------------------------------------------------------------------------
1 | // code is taken from §5.6/88
2 | #include
3 | #include
4 | #include "split.h"
5 |
6 | using std::vector;
7 | using std::string;
8 |
9 | vector split(const string& s)
10 | {
11 | vector ret;
12 | typedef string::size_type string_size;
13 | string_size i = 0;
14 |
15 | // invariant: we have processed characters [original value of i, i)
16 | while (i != s.size()) {
17 | // ignore leading blanks
18 | // invariant: characters in range [original i, current i) are all spaces
19 | while (i != s.size() && isspace(s[i]))
20 | ++i;
21 |
22 | // find end of next word
23 | string_size j = i;
24 | // invariant: none of the characters in range [original j, current j) is a space
25 | while (j != s.size() && !isspace(s[j]))
26 | ++j;
27 |
28 | // if we found some nonwhitespace characters
29 | if (i != j) {
30 | // copy from s starting at i and taking j - i chars
31 | ret.push_back(s.substr(i, j - i));
32 | i = j;
33 | }
34 | }
35 | return ret;
36 | }
--------------------------------------------------------------------------------
/Chapter 05/split.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_split_h
2 | #define GUARD_split_h
3 |
4 | #include
5 | #include
6 |
7 | std::vector split(const std::string&);
8 | #endif
--------------------------------------------------------------------------------
/Chapter 06/Student_info.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "grade.h"
6 | #include "median.h"
7 | #include "Student_info.h"
8 |
9 | using std::cout;
10 | using std::vector;
11 | using std::istream;
12 | using std::domain_error;
13 | using std::sort;
14 |
15 | // code is taken from §4.4/69
16 | bool compare(const Student_info& x, const Student_info& y)
17 | {
18 | return x.name < y.name;
19 | }
20 |
21 | // code is taken from §4.2.2/62
22 | istream& read(istream& is, Student_info& s)
23 | {
24 | // read and store the student's name and final grade
25 | is >> s.name >> s.midterm >> s.final;
26 |
27 | read_hw(is, s.homework); // read and store all the student's homework grades
28 | return is;
29 | }
30 |
31 | // code is taken from §4.1.3/57
32 | istream& read_hw(istream& in, vector& hw)
33 | {
34 | if (in) {
35 | // get rid of previous contetns
36 | hw.clear();
37 |
38 | // read homework grades
39 | double x;
40 | while (in >> x)
41 | hw.push_back(x);
42 |
43 | // clear the stream so that input will work for the next student
44 | in.clear();
45 | }
46 | return in;
47 | }
--------------------------------------------------------------------------------
/Chapter 06/Student_info.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_Student_info
2 | #define GUARD_Student_info
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | struct Student_info {
9 | std::string name;
10 | double midterm, final;
11 | std::vector homework;
12 | };
13 |
14 | bool compare(const Student_info&, const Student_info&);
15 | std::istream& read(std::istream&, Student_info&);
16 | std::istream& read_hw(std::istream&, std::vector&);
17 | #endif
--------------------------------------------------------------------------------
/Chapter 06/analysis.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_analysis_h
2 | #define GUARD_analysis_h
3 |
4 | #include
5 | #include
6 | #include
7 | #include "Student_info.h"
8 |
9 | double analysis(const std::vector