├── .gitignore ├── Chapter-2-Exercises ├── A-Sideways-Triangle.cpp ├── Decode-A-Message.cpp ├── Exercise-2-1.cpp ├── Exercise-2-2.cpp ├── Exercise-2-3.cpp ├── Half-of-a-Square.cpp └── Luhn-Checksum-Validation.cpp ├── Chapter-3-Exercises ├── Exercise-3-1.cpp ├── Exercise-3-2.cpp ├── Exercise-3-3.cpp ├── Exercise-3-4.cpp ├── Finding-the-Mode.cpp └── Highest-Average-Sales.cpp ├── Chapter-4-Exercises ├── Exercise-4-1.cpp ├── Exercise-4-2.cpp ├── Tracking-An-Unkown-Qty-of-Student-Records.cpp └── Variable-Length-String-Manipulation.cpp ├── Chapter-5-Exercises ├── Class Roster │ ├── Class-Roster.cpp │ ├── studentRecord.cpp │ └── studentRecord.h ├── Exercises-5-1-and-5-2 │ ├── Automobile.cpp │ ├── Automobile.h │ └── Exercise-5-1-and-5-2.cpp └── Unkown-Student-Records │ ├── Unkown-Student-Records.cpp │ ├── studentCollection.cpp │ ├── studentCollection.h │ ├── studentRecord.cpp │ └── studentRecord.h ├── Chapter-6-Exercises ├── Computing-the-Sum-of-an-Integer-Array.cpp ├── Counting-Negative-Numbers-in-a-Singly-Linked-List.cpp ├── Exercise-6-1.cpp └── Find-the-Largest-Value-in-a-Binary-Tree.cpp ├── Chapter-7-Exercises ├── Efficient-Traversal │ ├── Efficient-Traversal.cpp │ ├── scIterator.cpp │ ├── scIterator.h │ ├── studentCollection.cpp │ ├── studentCollection.h │ ├── studentRecord.cpp │ └── studentRecord.h └── The-First-Student │ ├── The-First-Student.cpp │ ├── studentCollection.cpp │ ├── studentCollection.h │ ├── studentRecord.cpp │ └── studentRecord.h └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Codeblocks Files 31 | *.cbp 32 | *.depend 33 | *.layout 34 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/A-Sideways-Triangle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: A Sideways Triangle 3 | * 4 | * Write a program that uses only two output statemetns, cout << "#" and 5 | * cout << "\n" to produce a pattern of hash symbols shaped like a sideways 6 | * triangle: 7 | * 8 | * # 9 | * ## 10 | * ### 11 | * #### 12 | * ### 13 | * ## 14 | * # 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | int main() 22 | { 23 | for (int row = 1; row <= 7; row++) 24 | { 25 | for (int hashNum = 1; hashNum <= 4 - abs(4 - row); hashNum++) 26 | { 27 | std::cout << "#"; 28 | } 29 | std::cout << "\n"; 30 | } 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Decode-A-Message.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Decode a Message 3 | * 4 | * A message has been encoded as a text stream that is read character by 5 | * character. The stream contains a series of comma-delimited integers, each 6 | * a positive number capable of being represented by a C++ int. However, the 7 | * character represented by a particular integer depends on the current 8 | * decoding mode. There are three modes: uppercase, lowercase, and 9 | * punctuation. 10 | * 11 | * In uppercase mode, each integer represents an uppercase letter: The 12 | * integer modulo 27 indicates the letter of the alphabet (where 1 = A 13 | * and so on). So an input value of 143 in uppercase mode would yeild the 14 | * letter H because 143 modulo 27 is 8 and H is the eighth letter in the 15 | * alphabet. 16 | * 17 | * The lowercase mode works the same but with lowercase lettters; the 18 | * remainder of dividing the integer by 27 represents the lowercase letter 19 | * (1 = a and so on). So an input value of 56 in lowercase mode would yeild 20 | * the letter b because 57 modulo 27 is 2 and b is the second letter in the 21 | * alphabet. 22 | * 23 | * In punctuation mode, the integer is instead considered a modulo 9, with 24 | * the interpretation given by Table 2-3 below. So 19 would yeild an 25 | * exclamation point because 19 modulo 9 is 1. 26 | * 27 | * At the beginning of each message, the decoding mode is uppercase letters. 28 | * Each time a modulo operation (by 27 or 9, depending on the mode) results 29 | * in 0, the decoding mode switches. If the current mode is uppercase, the 30 | * mode switches to lowercase letters. If the current mode is lowercase, the 31 | * mode switches to punctuations, and if it is punctuation, it switches back 32 | * to uppercase. 33 | * 34 | * Table 2-3: Punctuation Decoding Mode 35 | * Number Symbol 36 | * 1 ! 37 | * 2 ? 38 | * 3 , 39 | * 4 . 40 | * 5 (space) 41 | * 6 ; 42 | * 7 " 43 | * 8 ' 44 | */ 45 | 46 | #include 47 | 48 | int main() 49 | { 50 | char outputCharacter; 51 | enum modeType {UPPERCASE, LOWERCASE, PUNCTUATION}; 52 | modeType mode = UPPERCASE; 53 | char digitChar; 54 | do 55 | { 56 | digitChar = std::cin.get(); 57 | int number = (digitChar - '0'); 58 | digitChar = std::cin.get(); 59 | while((digitChar != 10) && (digitChar != ',')) 60 | { 61 | number = number * 10 + (digitChar - '0'); 62 | digitChar = std::cin.get(); 63 | } 64 | switch(mode) 65 | { 66 | case UPPERCASE: 67 | number = number % 27; 68 | outputCharacter = number + 'A' - 1; 69 | if (number == 0) 70 | { 71 | mode = LOWERCASE; 72 | continue; 73 | } 74 | break; 75 | case LOWERCASE: 76 | number = number % 27; 77 | outputCharacter = number + 'a' - 1; 78 | if (number == 0) 79 | { 80 | mode = PUNCTUATION; 81 | continue; 82 | } 83 | break; 84 | case PUNCTUATION: 85 | number = number % 9; 86 | switch(number) 87 | { 88 | case 1: outputCharacter = '!'; break; 89 | case 2: outputCharacter = '?'; break; 90 | case 3: outputCharacter = ','; break; 91 | case 4: outputCharacter = '.'; break; 92 | case 5: outputCharacter = ' '; break; 93 | case 6: outputCharacter = ';'; break; 94 | case 7: outputCharacter = '"'; break; 95 | case 8: outputCharacter = '\''; break; 96 | } 97 | if (number == 0) 98 | { 99 | mode = UPPERCASE; 100 | continue; 101 | } 102 | break; 103 | } 104 | std::cout << outputCharacter; 105 | } while(digitChar != 10); 106 | std::cout << '\n'; 107 | } 108 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Exercise-2-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 2-1 3 | * 4 | * Using only single-character output statements that output a hash mark, 5 | * a space, or an end-of-line symbol, write a program that outputs the 6 | * following shape: 7 | * 8 | * ######## 9 | * ###### 10 | * #### 11 | * ## 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | int main() 18 | { 19 | for(int row = 1; row <= 4; row++) 20 | { 21 | for (int space = 1; space <= (row - 1); space ++) 22 | { 23 | std::cout << ' '; 24 | } 25 | 26 | for (int hashNum = 1; hashNum <= 8 - 2 * (row - 1); hashNum++) 27 | { 28 | std::cout << '#'; 29 | } 30 | std::cout << "\n"; 31 | } 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Exercise-2-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 2-2 3 | * 4 | * Using only single-character output statements that output a hash mark, 5 | * a space, or an end-of-line symbol, write a program that outputs the 6 | * following shape: 7 | * 8 | * ## 9 | * #### 10 | * ###### 11 | * ######## 12 | * ######## 13 | * ###### 14 | * #### 15 | * ## 16 | */ 17 | 18 | #include 19 | 20 | int main() 21 | { 22 | // upper half 23 | for(int row = 1; row <= 4; row++) 24 | { 25 | for(int space = 1; space <= 3 - (row - 1); space++) 26 | { 27 | std::cout << ' '; 28 | } 29 | 30 | for (int hashNum = 1; hashNum <= 2 + 2 * (row - 1); hashNum++) 31 | { 32 | std::cout << '#'; 33 | } 34 | std::cout << '\n'; 35 | } 36 | 37 | // lower half 38 | for(int row = 1; row <= 4; row++) 39 | { 40 | 41 | for (int space = 1; space <= (row - 1); space ++) 42 | { 43 | std::cout << ' '; 44 | } 45 | 46 | for (int hashNum = 1; hashNum <= 8 - 2 * (row - 1); hashNum++) 47 | { 48 | std::cout << '#'; 49 | } 50 | std::cout << '\n'; 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Exercise-2-3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 2-2 3 | * 4 | * Using only single-character output statements that output a hash mark, 5 | * a space, or an end-of-line symbol, write a program that outputs the 6 | * following shape: 7 | * 8 | * # # 9 | * ## ## 10 | * ### ### 11 | * ######## 12 | * ######## 13 | * ### ### 14 | * ## ## 15 | * # # 16 | */ 17 | 18 | #include 19 | 20 | int main() 21 | { 22 | // Top half 23 | for (int row = 1; row <= 4; row++) 24 | { 25 | for (int space = 1; space <= (row - 1); space++) 26 | { 27 | std::cout << ' '; 28 | } 29 | 30 | for (int hashNum = 1; hashNum <= row; hashNum++) 31 | { 32 | std::cout << '#'; 33 | } 34 | 35 | for (int space = 1; space <= 14 - 2 * ((row - 1) + row); space++) 36 | { 37 | std::cout << ' '; 38 | } 39 | 40 | for (int hashNum = 1; hashNum <= row; hashNum++) 41 | { 42 | std::cout << '#'; 43 | } 44 | std::cout << '\n'; 45 | } 46 | 47 | // Bottom half 48 | for (int row = 1; row <= 4; row++) 49 | { 50 | for (int space = 1; space <= (4 - row); space++) 51 | { 52 | std::cout << ' '; 53 | } 54 | 55 | for (int hashNum = 1; hashNum <= (5 - row); hashNum++) 56 | { 57 | std::cout << '#'; 58 | } 59 | 60 | for (int space = 1; space <= 14 - 2 * ((4 - row) + (5 - row)); space++) 61 | { 62 | std::cout << ' '; 63 | } 64 | 65 | for (int hashNum = 1; hashNum <= (5 - row); hashNum++) 66 | { 67 | std::cout << '#'; 68 | } 69 | std::cout << '\n'; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Half-of-a-Square.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Half of a Square 3 | * 4 | * Write a program that uses only two output statemetns, cout << "#" and 5 | * cout << "\n" to produce a pattern of hash symbols shaped like half of a 6 | * perfect 5 x 5 square (or a right triangle): 7 | * 8 | * ##### 9 | * #### 10 | * ### 11 | * ## 12 | * # 13 | */ 14 | 15 | #include 16 | 17 | int main() 18 | { 19 | for(int row = 1; row <= 5; row++) 20 | { 21 | for (int hashNum = 1; hashNum <= 6 - row; hashNum++) 22 | { 23 | std::cout << "#"; 24 | } 25 | std::cout << "\n"; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter-2-Exercises/Luhn-Checksum-Validation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Luhn Checksum Validation 3 | * 4 | * The Luhn formula is a widely used system for validating identification 5 | * numbers. Using the original number, double the value of every other digit. 6 | * Then add the values of the individual digits together (if a doubled value 7 | * now has two digits, add the digits individually). The Identification number 8 | * is valid if the sum is divisible by 10. 9 | * 10 | * Write a program that takes an identification number of arbitrary length and 11 | * determines wheter the number is valid under the Luhn formula. The program 12 | * must process each character before reading the next one. 13 | */ 14 | 15 | #include 16 | 17 | int doubleDigitValue(int digit); 18 | 19 | int main() 20 | { 21 | char digit; 22 | int oddLengthChecksum = 0; 23 | int evenLengthChecksum = 0; 24 | int position = 1; 25 | 26 | std::cout << "Enter a number: "; 27 | digit = std::cin.get(); 28 | 29 | while(digit != 10) 30 | { 31 | 32 | if(position % 2 == 0) 33 | { 34 | oddLengthChecksum += doubleDigitValue(digit - '0'); 35 | evenLengthChecksum += digit - '0'; 36 | } 37 | else 38 | { 39 | oddLengthChecksum += digit - '0'; 40 | evenLengthChecksum += doubleDigitValue(digit - '0'); 41 | } 42 | std::cout << digit << " " << evenLengthChecksum << " " << oddLengthChecksum << '\n'; 43 | digit = std::cin.get(); 44 | position++; 45 | } 46 | 47 | int checksum; 48 | if ((position - 1) % 2 == 0) 49 | { 50 | checksum = evenLengthChecksum; 51 | } 52 | else 53 | { 54 | checksum = oddLengthChecksum; 55 | } 56 | 57 | std::cout << "Checksum is " << checksum << ".\n"; 58 | 59 | if(checksum % 10 == 0) 60 | { 61 | std::cout << "Checksum is divisible by 10. Valid.\n"; 62 | } 63 | else 64 | { 65 | std::cout << "Checksum is not divisible by 10. Invalid.\n"; 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | int doubleDigitValue(int digit) 72 | { 73 | int doubledDigit = digit * 2; 74 | int sum; 75 | if (doubledDigit >= 10) sum = 1 + doubledDigit % 10; 76 | else sum = doubledDigit; 77 | return sum; 78 | } 79 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Exercise-3-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 3-1 3 | * 4 | * Are you disappointed we didn't do more with sorting? I'm here to help. 5 | * To make sure you are comfortable with qsort, write code that uses the 6 | * function to sort an array of our student struct. First have it sort by 7 | * grade, and then try it again using the student ID. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | struct student 15 | { 16 | int grade; 17 | int studentID; 18 | std::string name; 19 | }; 20 | 21 | // forward declare compare function for qsort by grade 22 | int compareGrades(const void* A, const void* B); 23 | 24 | // forward declare compare function for qsort by ID 25 | int compareID(const void* A, const void* B); 26 | 27 | int main() 28 | { 29 | const int ARRAY_SIZE = 10; 30 | student studentArray[ARRAY_SIZE] = { 31 | {87, 10001, "Fred"}, 32 | {28, 10002, "Tom"}, 33 | {100, 10003, "Alistair"}, 34 | {78, 10004, "Sasha"}, 35 | {84, 10005, "Erin"}, 36 | {98, 10006, "Belinda"}, 37 | {75, 10007, "Leslie"}, 38 | {70, 10008, "Candy"}, 39 | {81, 10009, "Aretha"}, 40 | {68, 10010, "Veronica"} 41 | }; 42 | 43 | // print unsorted array to console 44 | std::cout << "Initial Array\n"; 45 | for (int i = 0; i < ARRAY_SIZE; i++) 46 | { 47 | std::cout << studentArray[i].grade << '\t' 48 | << studentArray[i].studentID << '\t' 49 | << studentArray[i].name << '\n'; 50 | } 51 | 52 | std::cout << '\n'; 53 | 54 | qsort(studentArray, ARRAY_SIZE, sizeof(student), compareGrades); 55 | 56 | // print sorted array to console 57 | std::cout << "Sorted by grade\n"; 58 | for (int i = 0; i < ARRAY_SIZE; i++) 59 | { 60 | std::cout << studentArray[i].grade << '\t' 61 | << studentArray[i].studentID << '\t' 62 | << studentArray[i].name << '\n'; 63 | } 64 | 65 | std::cout << '\n'; 66 | 67 | qsort(studentArray, ARRAY_SIZE, sizeof(student), compareID); 68 | 69 | // print sorted array to console 70 | std::cout << "Sorted by student ID\n"; 71 | for (int i = 0; i < ARRAY_SIZE; i++) 72 | { 73 | std::cout << studentArray[i].grade << '\t' 74 | << studentArray[i].studentID << '\t' 75 | << studentArray[i].name << '\n'; 76 | } 77 | 78 | return 0; 79 | } 80 | 81 | // compare function for qsort by grade 82 | int compareGrades(const void* A, const void* B) 83 | { 84 | student* studentA = (student*)(A); 85 | student* studentB = (student*)(B); 86 | return (studentA->grade - studentB->grade); 87 | } 88 | 89 | // compare function for qsort by ID 90 | int compareID(const void* A, const void* B) 91 | { 92 | student* studentA = (student*)(A); 93 | student* studentB = (student*)(B); 94 | return (studentA->studentID - studentB->studentID); 95 | } 96 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Exercise-3-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 3-2 3 | * 4 | * Rewrite the code that finds the agent with the best monthly sales average 5 | * so that it finds the agent with the highest median sales. As stated 6 | * earlier, the median of a set of values is the "one in the middle," such 7 | * that half of the other values are higher and half of the other values are 8 | * lower. If there is an even number of values, the median is the simple 9 | * average of the two values in the middle. For example, in the set 10 | * 10, 6, 2, 14, 7, 9, the values in the middle are 7 and 9. The average of 11 | * 7 and 9 is 8, so 8 is the median. 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | const int NUM_AGENTS = 3; 18 | const int NUM_MONTHS = 12; 19 | 20 | // compare function for qsort 21 | int compare(const void* A, const void* B); 22 | 23 | // calculate average of values in array 24 | double arrayAverage(int intArray[], int ARRAY_SIZE); 25 | 26 | // calculate median of array 27 | double arrayMedian(int intArray[], int ARRAY_SIZE); 28 | 29 | // output the contents of a multidimensional array to the console window 30 | template 31 | void printMultArray(T(&theArray)[ROWS][COLUMNS]); 32 | 33 | int main() 34 | { 35 | 36 | int sales[NUM_AGENTS][NUM_MONTHS] = { 37 | {1856, 498, 30924, 87478, 328, 2653, 387, 3754, 387587, 2873, 276, 32}, 38 | {5865, 5456, 3983, 6464, 9957, 4785, 3875, 3838, 4959, 1122, 7766, 2534}, 39 | {23, 55, 67, 99, 265, 376, 232, 223, 4546, 564, 4544, 3434} 40 | }; 41 | 42 | std::cout << "Raw sales array\n"; 43 | printMultArray(sales); 44 | 45 | // find highest average value calculated from the agent arrays 46 | double highestAverage = arrayAverage(sales[0], 12); 47 | for (int agent = 1; agent < NUM_AGENTS; agent++) 48 | { 49 | double agentAverage = arrayAverage(sales[agent], 12); 50 | if (agentAverage > highestAverage) 51 | { 52 | highestAverage = agentAverage; 53 | } 54 | } 55 | 56 | std::cout << "\nHighest monthly average: " << highestAverage << '\n'; 57 | 58 | // sort each agent array 59 | for (int agent = 0; agent < NUM_AGENTS; agent++) 60 | { 61 | qsort(sales[agent], NUM_MONTHS, sizeof(int), compare); 62 | } 63 | 64 | std::cout << '\n'; 65 | std::cout << "Sorted Sales Array\n"; 66 | 67 | printMultArray(sales); 68 | 69 | double highestMedian = arrayMedian(sales[0], 12); 70 | for (int agent = 1; agent < NUM_AGENTS; agent++) 71 | { 72 | double agentMedian = arrayMedian(sales[agent], 12); 73 | if (agentMedian > highestMedian) 74 | { 75 | highestMedian = agentMedian; 76 | } 77 | } 78 | 79 | std::cout << "\nHighest monthly median sales: " << highestMedian << '\n'; 80 | 81 | return 0; 82 | } 83 | 84 | // compare function for qsort 85 | int compare(const void* A, const void* B) 86 | { 87 | int* pA = (int*) A; 88 | int* pB = (int*) B; 89 | return *pA - *pB; 90 | } 91 | 92 | // calculate average of values in array 93 | double arrayAverage(int intArray[], int ARRAY_SIZE) 94 | { 95 | double sum = 0; 96 | for (int i = 0; i < ARRAY_SIZE; i++) 97 | { 98 | sum += intArray[i]; 99 | } 100 | double average = sum / ARRAY_SIZE; 101 | return average; 102 | } 103 | 104 | // calculate median of array 105 | double arrayMedian(int intArray[], int ARRAY_SIZE) 106 | { 107 | if (ARRAY_SIZE % 2 == 0) 108 | { 109 | int indexOne = ARRAY_SIZE / 2; 110 | int indexTwo = indexOne + 1; 111 | 112 | return (intArray[indexOne - 1] + intArray[indexTwo - 1]) / 2.0; 113 | } 114 | 115 | int index = (ARRAY_SIZE / 2) + 1; 116 | return intArray[index - 1]; 117 | } 118 | 119 | // output the contents of a multidimensional array to the console window 120 | template 121 | void printMultArray(T (&theArray)[ROWS][COLUMNS]) 122 | { 123 | for (int agent = 0; agent < ROWS; agent++) 124 | { 125 | std::cout << "Agent " << agent + 1 << ": "; 126 | for (int month = 0; month < COLUMNS; month++) 127 | { 128 | std::cout << theArray[agent][month] << ' '; 129 | } 130 | std::cout << '\n'; 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Exercise-3-3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 3-3 3 | * 4 | * Write a bool function that is passed an array and the number of elements 5 | * in that array and determines wheter the data in the array is sorted. This 6 | * should require only one pass! 7 | */ 8 | 9 | #include 10 | 11 | bool isSorted(int intArray[], int SIZE); 12 | 13 | int main() 14 | { 15 | int one[5] = {1, 2, 3, 4, 5}; 16 | 17 | for (int i = 0; i < 5; i++) 18 | { 19 | std::cout << one[i] << " "; 20 | } 21 | std::cout << std::endl; 22 | 23 | if (isSorted(one, 5)) 24 | { 25 | std::cout << "Sorted\n\n"; 26 | } 27 | else 28 | { 29 | std::cout << "Not Sorted\n\n"; 30 | } 31 | 32 | std::cout << std::endl; 33 | 34 | int two[4] = {2, 3, 1, 4}; 35 | 36 | for (int i = 0; i < 4; i++) 37 | { 38 | std::cout << two[i] << " "; 39 | } 40 | std::cout << std::endl; 41 | 42 | if (isSorted(two, 4)) 43 | { 44 | std::cout << "Sorted\n\n"; 45 | } 46 | else 47 | { 48 | std::cout << "Not Sorted\n\n"; 49 | } 50 | 51 | std::cout << std::endl; 52 | 53 | int three[4] = {1, 1, 2, 2}; 54 | 55 | for (int i = 0; i < 4; i++) 56 | { 57 | std::cout << three[i] << " "; 58 | } 59 | std::cout << std::endl; 60 | 61 | if (isSorted(three, 4)) 62 | { 63 | std::cout << "Sorted\n\n"; 64 | } 65 | else 66 | { 67 | std::cout << "Not Sorted\n\n"; 68 | } 69 | 70 | } 71 | 72 | bool isSorted(int intArray[], int SIZE) 73 | { 74 | int current = intArray[0]; 75 | for (int index = 1; index < SIZE; index++) 76 | { 77 | if (current > intArray[index]) 78 | { 79 | return false; 80 | } 81 | current = intArray[index]; 82 | } 83 | return true; 84 | } 85 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Exercise-3-4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 3-4 3 | * 4 | * Here's a variation on the array of const values. Write a program for 5 | * creating a substitution cipher problem. In a substitution cipher problem, 6 | * all messages are made of uppercase letters and punctuation. The original 7 | * message is called the plaintext, and you create the ciphertext by 8 | * substituting each letter with another letter (for example, each C could 9 | * become an X). For this problem, hard-code a cons array of 26 char elements 10 | * for the cipher, and have your program read a plaintext message and output 11 | * the equivalent ciphertext. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | std::string encode(std::string plaintext, const char cipher[]); 19 | 20 | int main() 21 | { 22 | 23 | const char cipher[26] = {'B', 'C', 'M', 'E', 'F', 'G', 'H', 'S', 'J', 24 | 'K', 'L', 'D', 'N', 'O', 'W', 'Q', 'R', 'I', 25 | 'Z', 'U', 'V', 'Q' , 'X', 'Y', 'T', 'A'}; 26 | 27 | std::string plaintext = "This is just a test."; 28 | 29 | std::string ciphertext = encode(plaintext, cipher); 30 | 31 | std::cout << ciphertext; 32 | 33 | return 0; 34 | } 35 | 36 | std::string encode(std::string plaintext, const char cipher[]) 37 | { 38 | // convert string to uppercase and encode message 39 | std::locale loc; 40 | for (std::string::size_type i = 0; i < plaintext.length(); ++i) 41 | { 42 | plaintext[i] = std::toupper(plaintext[i], loc); 43 | 44 | if ((plaintext[i] > 64) && (plaintext[i] < 96)) 45 | { 46 | plaintext[i] = cipher[plaintext[i] - 65]; 47 | } 48 | } 49 | 50 | return plaintext; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Finding-the-Mode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Finding the Mode 3 | * 4 | * In statistics, the mode of a set of values is the value that appears most 5 | * often. Write code that processes an array of survey data, where the survey 6 | * takers have responded to a question with a number in the range 1-10, to 7 | * determine the mode of the data set. For our purpose, if multiple modes 8 | * exist, any may be chosen. 9 | */ 10 | 11 | #include 12 | 13 | int main() 14 | { 15 | const int ARRAY_SIZE = 12; 16 | int surveyData[ARRAY_SIZE] = {4, 7, 3, 8, 9, 7, 3, 9, 9, 3, 3, 10}; 17 | 18 | std::cout << "Find the mode of {4, 7, 3, 8, 9, 7, 3, 9, 9, 3, 3, 10}" << '\n'; 19 | 20 | const int MAX_RESPONSE = 10; 21 | int histogram[MAX_RESPONSE]; 22 | 23 | // initialize values to 0 24 | for(int i = 0; i < MAX_RESPONSE; i++) 25 | { 26 | histogram[i] = 0; 27 | } 28 | 29 | // add to histogram count 30 | for(int i = 0; i < ARRAY_SIZE; i++) 31 | { 32 | histogram[surveyData[i] - 1]++; 33 | } 34 | 35 | int mostFrequent = 0; 36 | for (int i = 1; i < MAX_RESPONSE; i++) 37 | { 38 | if (histogram[i] > histogram[mostFrequent]) mostFrequent = i; 39 | } 40 | mostFrequent++; 41 | 42 | std::cout << "The mode is: " << mostFrequent << '\n'; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter-3-Exercises/Highest-Average-Sales.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Example code for finding highest average in multidimensional array 3 | */ 4 | 5 | #include 6 | 7 | double arrayAverage(int intArray[], int ARRAY_SIZE); 8 | 9 | int main() 10 | { 11 | const int NUM_AGENTS = 3; 12 | const int NUM_MONTHS = 12; 13 | int sales[NUM_AGENTS][NUM_MONTHS] = { 14 | {1856, 498, 30924, 87478, 328, 2653, 387, 3754, 387587, 2873, 276, 32}, 15 | {5865, 5456, 3983, 6464, 9957, 4785, 3875, 3838, 4959, 1122, 7766, 2534}, 16 | {23, 55, 67, 99, 265, 376, 232, 223, 4546, 564, 4544, 3434} 17 | }; 18 | 19 | double highestAverage = arrayAverage(sales[0], 12); 20 | for (int agent = 1; agent < NUM_AGENTS; agent++) 21 | { 22 | double agentAverage = arrayAverage(sales[agent], 12); 23 | if (agentAverage > highestAverage) 24 | { 25 | highestAverage = agentAverage; 26 | } 27 | } 28 | 29 | std::cout << "Highest monthly average: " << highestAverage << '\n'; 30 | 31 | return 0; 32 | } 33 | 34 | double arrayAverage(int intArray[], int ARRAY_SIZE) 35 | { 36 | double sum = 0; 37 | for (int i = 0; i < ARRAY_SIZE; i++) 38 | { 39 | sum += intArray[i]; 40 | } 41 | double average = sum / ARRAY_SIZE; 42 | return average; 43 | } 44 | -------------------------------------------------------------------------------- /Chapter-4-Exercises/Exercise-4-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 4-1 3 | * 4 | * Design your own: Take a problem that you already know how to solve using 5 | * an array but that is limited by the size of the array. Rewrite the code to 6 | * remove that limitation using a dynamically allocated array. 7 | */ 8 | 9 | #include 10 | 11 | int main() 12 | { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Chapter-4-Exercises/Exercise-4-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 4-2 3 | * 4 | * For our dynamically allocated strings, create a function substring that 5 | * takes three parameters: an arrayString, a starting position integer, and 6 | * an integer length of characters. The function returns a pointer to a new 7 | * dynamically allocated string array. This string array contains the 8 | * characters in the original string, starting at the specified position 9 | * for the specified length. The original string is unaffected by the 10 | * operation. So if the original string abcdefg, the position was 3, and the 11 | * length was 4, then the new string would contain cdef. 12 | */ 13 | 14 | #include 15 | #include 16 | 17 | typedef char *arrayString; 18 | 19 | char characterAt(arrayString s, int position); 20 | 21 | int length(arrayString s); 22 | 23 | void append(arrayString &s, char c); 24 | 25 | void appendTester(); 26 | 27 | void concatenate(arrayString &s1, arrayString &s2); 28 | 29 | void concatenateTester(); 30 | 31 | arrayString substring(arrayString s, int start, int length); 32 | 33 | void substringTester(); 34 | 35 | int main() 36 | { 37 | appendTester(); 38 | 39 | std::cout << std::endl; 40 | 41 | concatenateTester(); 42 | 43 | std::cout << std::endl; 44 | 45 | substringTester(); 46 | } 47 | 48 | char characterAt(arrayString s, int position) 49 | { 50 | return s[position]; 51 | } 52 | 53 | int length(arrayString s) 54 | { 55 | int count = 0; 56 | while (s[count] != 0) 57 | { 58 | count++; 59 | } 60 | return count; 61 | } 62 | 63 | void append(arrayString &s, char c) 64 | { 65 | int oldLength = length(s); 66 | 67 | arrayString newS = new char[oldLength + 2]; 68 | for (int i = 0; i < oldLength; i++) 69 | { 70 | newS[i] = s[i]; 71 | } 72 | 73 | newS[oldLength] = c; 74 | newS[oldLength + 1] = 0; 75 | delete[] s; 76 | s = newS; 77 | } 78 | 79 | void appendTester() 80 | { 81 | arrayString a = new char[5]; 82 | a[0] = 't'; a[1] = 'e'; a[2] = 's'; a[3] = 't'; a[4] = 0; 83 | append(a, '!'); 84 | std::cout << a << '\n'; 85 | 86 | arrayString b = new char[1]; 87 | b[0] = 0; 88 | append(b, '!'); 89 | std::cout << b << '\n'; 90 | } 91 | 92 | void concatenate(arrayString &s1, arrayString &s2) 93 | { 94 | int s1_OldLength = length(s1); 95 | int s2_Length = length(s2); 96 | int s1_NewLength = s1_OldLength + s2_Length; 97 | 98 | arrayString newS = new char[s1_NewLength + 1]; 99 | // copy s1 into beginning of newS 100 | for (int i = 0; i < s1_OldLength; i++) 101 | { 102 | newS[i] = s1[i]; 103 | } 104 | // add s2 to end of newS 105 | for (int i = 0; i < s2_Length; i++) 106 | { 107 | newS[s1_OldLength + i] = s2[i]; 108 | } 109 | // add the null character to end of newS 110 | newS[s1_NewLength] = 0; 111 | // deallocate s1 from heap 112 | delete[] s1; 113 | s1 = newS; 114 | } 115 | 116 | void concatenateTester() 117 | { 118 | arrayString a = new char[5]; 119 | a[0] = 't'; a[1] = 'e'; a[2] = 's'; a[3] = 't'; a[4] = 0; 120 | arrayString b = new char[4]; 121 | b[0] = 'b'; b[1] = 'e'; b[2] = 'd'; b[3] = 0; 122 | concatenate(a, b); 123 | std::cout << a << '\n'; 124 | 125 | std::cout << std::endl; 126 | 127 | arrayString c = new char[5]; 128 | c[0] = 't'; c[1] = 'e'; c[2] = 's'; c[3] = 't'; c[4] = 0; 129 | arrayString d = new char[1]; 130 | d[0] = 0; 131 | concatenate(d, c); 132 | std::cout << c << "----" << d << '\n'; 133 | std::cout << (void *) c << "----" << (void *) d << '\n'; 134 | } 135 | 136 | arrayString substring(arrayString s, int start, int len) 137 | { 138 | // add check to avoid calling length past end of string 139 | arrayString newS = new char[len + 1]; 140 | // copy selected section into new string 141 | int count = 0; 142 | for (int i = start; i < start + len; i++) 143 | { 144 | newS[count] = s[i]; 145 | count++; 146 | } 147 | newS[len] = 0; 148 | delete[] s; 149 | return newS; 150 | } 151 | 152 | void substringTester() 153 | { 154 | arrayString a = new char[8]; 155 | a[0] = 't'; a[1] = 'e'; a[2] = 's'; a[3] = 't'; a[4] = 'i'; a[5] = 'n'; 156 | a[6] = 'g'; a[7] = 0; 157 | std::cout << substring(a, 1, 4); 158 | } 159 | 160 | -------------------------------------------------------------------------------- /Chapter-4-Exercises/Tracking-An-Unkown-Qty-of-Student-Records.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Tracking an Unknown Quantity of Student Records 3 | * 4 | * In this problem, you will write functions to store and manipulate a 5 | * collection of student records. A student record contains a student 6 | * number and a grade, both integers. The following functions are to be 7 | * implemented. 8 | * 9 | * addRecord - This function takes a pointer to a collection of student 10 | * records (a student number and a grade), and it adds a new record with 11 | * this data to the collection. 12 | * 13 | * averageRecord - This function takes a pointer to a collection of student 14 | * records and returns the simple average of student grades in the collection 15 | * as a double. 16 | * 17 | * The collection can be of any size. The addRecord operation is expected to 18 | * be called frequently, so it must be implemented efficiently. 19 | */ 20 | 21 | #include 22 | 23 | struct listNode 24 | { 25 | int studentNum; 26 | int grade; 27 | listNode *next; 28 | }; 29 | 30 | typedef listNode *studentCollection; 31 | 32 | // adds a node to the front of the linked list 33 | void addRecord(studentCollection &sc, int stuNum, int gr); 34 | 35 | double averageRecord(studentCollection sc); 36 | 37 | int main() 38 | { 39 | studentCollection sc; 40 | 41 | // declare each node in the list 42 | listNode *node1 = new listNode; 43 | node1->studentNum = 1001; node1->grade = 78; 44 | 45 | listNode *node2 = new listNode; 46 | node2->studentNum = 1012; node2->grade = 93; 47 | 48 | listNode *node3 = new listNode; 49 | node3->studentNum = 1076; node3->grade = 85; 50 | 51 | // link the nodes together to form the linked list 52 | sc = node1; 53 | node1->next = node2; 54 | node2->next = node3; 55 | node3->next = NULL; 56 | 57 | // set nodes to null to avoid cross-linking problems 58 | node1 = node2 = node3 = NULL; 59 | 60 | double avg = averageRecord(sc); 61 | 62 | std::cout << "Average = " << avg << '\n'; 63 | } 64 | 65 | // adds a node to the front of the linked list 66 | void addRecord(studentCollection &sc, int stuNum, int gr) 67 | { 68 | listNode *newNode = new listNode; 69 | newNode->studentNum = stuNum; 70 | newNode->grade = gr; 71 | newNode->next = sc; 72 | sc = newNode; 73 | } 74 | 75 | double averageRecord(studentCollection sc) 76 | { 77 | // prevent a divide by 0 error 78 | if (sc == NULL) return 0; 79 | 80 | int count = 0; 81 | double sum = 0.0; 82 | listNode *loopPtr = sc; 83 | 84 | while(loopPtr != NULL) 85 | { 86 | sum += loopPtr->grade; 87 | count++; 88 | loopPtr = loopPtr->next; 89 | } 90 | 91 | double average = sum / count; 92 | 93 | return average; 94 | } 95 | -------------------------------------------------------------------------------- /Chapter-4-Exercises/Variable-Length-String-Manipulation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Variable-Length String Manipulation 3 | * 4 | * Write heap-based implementations for three required string functions: 5 | * 6 | * append - This function takes a string and a character and appends the 7 | * character to the end of the string. 8 | * 9 | * concatenate - This function takes two strings and appends the characters 10 | * of the second string onto the first. 11 | * 12 | * characterAt - This function takes a string and a number and returns the 13 | * character at that position in the string (with the first character in the 14 | * string numbered zero). 15 | * 16 | * Write the code with the assumption that characterAt will be called 17 | * frequently while the other two functions will be called reletively seldom. 18 | * The relative efficiency of the operations should reflect the calling 19 | * frequency. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | typedef char *arrayString; 26 | 27 | char characterAt(arrayString s, int position); 28 | 29 | int length(arrayString s); 30 | 31 | void append(arrayString &s, char c); 32 | 33 | void appendTester(); 34 | 35 | void concatenate(arrayString &s1, arrayString &s2); 36 | 37 | void concatenateTester(); 38 | 39 | int main() 40 | { 41 | appendTester(); 42 | 43 | std::cout << std::endl; 44 | 45 | concatenateTester(); 46 | } 47 | 48 | char characterAt(arrayString s, int position) 49 | { 50 | return s[position]; 51 | } 52 | 53 | int length(arrayString s) 54 | { 55 | int count = 0; 56 | while (s[count] != 0) 57 | { 58 | count++; 59 | } 60 | return count; 61 | } 62 | 63 | void append(arrayString &s, char c) 64 | { 65 | int oldLength = length(s); 66 | 67 | arrayString newS = new char[oldLength + 2]; 68 | for (int i = 0; i < oldLength; i++) 69 | { 70 | newS[i] = s[i]; 71 | } 72 | 73 | newS[oldLength] = c; 74 | newS[oldLength + 1] = 0; 75 | delete[] s; 76 | s = newS; 77 | } 78 | 79 | void appendTester() 80 | { 81 | arrayString a = new char[5]; 82 | a[0] = 't'; a[1] = 'e'; a[2] = 's'; a[3] = 't'; a[4] = 0; 83 | append(a, '!'); 84 | std::cout << a << '\n'; 85 | 86 | arrayString b = new char[1]; 87 | b[0] = 0; 88 | append(b, '!'); 89 | std::cout << b << '\n'; 90 | } 91 | 92 | void concatenate(arrayString &s1, arrayString &s2) 93 | { 94 | int s1_OldLength = length(s1); 95 | int s2_Length = length(s2); 96 | int s1_NewLength = s1_OldLength + s2_Length; 97 | 98 | arrayString newS = new char[s1_NewLength + 1]; 99 | // copy s1 into beginning of newS 100 | for (int i = 0; i < s1_OldLength; i++) 101 | { 102 | newS[i] = s1[i]; 103 | } 104 | // add s2 to end of newS 105 | for (int i = 0; i < s2_Length; i++) 106 | { 107 | newS[s1_OldLength + i] = s2[i]; 108 | } 109 | // add the null character to end of newS 110 | newS[s1_NewLength] = 0; 111 | // deallocate s1 from heap 112 | delete[] s1; 113 | s1 = newS; 114 | } 115 | 116 | void concatenateTester() 117 | { 118 | arrayString a = new char[5]; 119 | a[0] = 't'; a[1] = 'e'; a[2] = 's'; a[3] = 't'; a[4] = 0; 120 | arrayString b = new char[4]; 121 | b[0] = 'b'; b[1] = 'e'; b[2] = 'd'; b[3] = 0; 122 | concatenate(a, b); 123 | std::cout << a << '\n'; 124 | 125 | std::cout << std::endl; 126 | 127 | arrayString c = new char[5]; 128 | c[0] = 't'; c[1] = 'e'; c[2] = 's'; c[3] = 't'; c[4] = 0; 129 | arrayString d = new char[1]; 130 | d[0] = 0; 131 | concatenate(d, c); 132 | std::cout << c << "----" << d << '\n'; 133 | std::cout << (void *) c << "----" << (void *) d << '\n'; 134 | } 135 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Class Roster/Class-Roster.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Class Roster 3 | * 4 | * Design a class or set of classes for use in a program that maintains a 5 | * roster. For each student, store the student's name, ID, and final grade 6 | * score in the range 0 - 100. The program will allow student records to be 7 | * added or removed; display the record of a particular student, identified 8 | * by ID, with the grade displayed as a number and as a letter; and display 9 | * the average score for the class. The appropriate letter grade for a 10 | * particular score is shown in table 5-1. 11 | * 12 | * Table 5-1: Letter Grades 13 | * Score Range Letter Grade 14 | * 93-100 A 15 | * 90-92 A- 16 | * 87-89 B+ 17 | * 83-86 B 18 | * 80-82 B- 19 | * 77-79 C+ 20 | * 73-76 C 21 | * 70-72 C- 22 | * 67-69 D+ 23 | * 60-66 D 24 | * 0-59 F 25 | */ 26 | 27 | #include 28 | #include 29 | #include "studentRecord.h" 30 | 31 | int main() 32 | { 33 | studentRecord Tom(97, 1, "Tom Gerard"); 34 | 35 | std::cout << Tom.name() << '\t' << Tom.studentID() << '\t' 36 | << Tom.grade() << '\t' << Tom.letterGrade() << std::endl; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Class Roster/studentRecord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentRecord.h" 3 | 4 | studentRecord::studentRecord() 5 | { 6 | setGrade(0); 7 | setStudentID(-1); 8 | setName(""); 9 | } 10 | 11 | studentRecord::studentRecord(int newGrade, int newID, std::string newName) 12 | { 13 | setGrade(newGrade); 14 | setStudentID(newID); 15 | setName(newName); 16 | } 17 | 18 | int studentRecord::grade() 19 | { 20 | return _grade; 21 | } 22 | 23 | bool studentRecord::isValidGrade(int grade) 24 | { 25 | if ((grade >= 0) && (grade <= 100)) 26 | { 27 | return true; 28 | } 29 | else 30 | { 31 | return false; 32 | } 33 | } 34 | 35 | 36 | void studentRecord::setGrade(int newGrade) 37 | { 38 | if (isValidGrade(newGrade)) 39 | { 40 | _grade = newGrade; 41 | } 42 | } 43 | 44 | int studentRecord::studentID() 45 | { 46 | return _studentID; 47 | } 48 | 49 | void studentRecord::setStudentID(int newID) 50 | { 51 | _studentID = newID; 52 | } 53 | 54 | 55 | std::string studentRecord::name() 56 | { 57 | return _name; 58 | } 59 | 60 | void studentRecord::setName(std::string newName) 61 | { 62 | _name = newName; 63 | } 64 | 65 | std::string studentRecord::letterGrade() 66 | { 67 | if(!isValidGrade(_grade)) return "ERROR"; 68 | 69 | const int NUMBER_CATEGORIES = 11; 70 | const std::string GRADE_LETTER[NUMBER_CATEGORIES] = { "F", "D", "D+", "C-", 71 | "C", "C+", "B-", "B", "B+", "A-", "A" }; 72 | const int LOWEST_GRADE_SCORE[NUMBER_CATEGORIES] = { 0, 60, 67, 70, 73, 77, 73 | 80, 83, 87, 90, 93 }; 74 | 75 | int category = 0; 76 | while (category < NUMBER_CATEGORIES && LOWEST_GRADE_SCORE[category] <= _grade) 77 | { 78 | category++; 79 | } 80 | return GRADE_LETTER[category - 1]; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Class Roster/studentRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTRECORD_H 2 | #define STUDENTRECORD_H 3 | 4 | #include 5 | 6 | class studentRecord 7 | { 8 | public: 9 | studentRecord(); 10 | studentRecord(int newGrade, int newID, std::string newName); 11 | int grade(); 12 | bool isValidGrade(int grade); 13 | void setGrade(int newGrade); 14 | int studentID(); 15 | void setStudentID(int newID); 16 | std::string name(); 17 | void setName(std::string newName); 18 | std::string letterGrade(); 19 | private: 20 | int _grade; 21 | int _studentID; 22 | std::string _name; 23 | }; 24 | 25 | #endif // STUDENTRECORD_H 26 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Exercises-5-1-and-5-2/Automobile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Automobile.h" 4 | 5 | Automobile::Automobile() : 6 | mManufacturer("unknown"), mModel("unknown"), mYear(-1) 7 | { 8 | 9 | } 10 | 11 | Automobile::Automobile(std::string manufacturer, std::string model, int year) : 12 | mManufacturer(manufacturer), mModel(model), mYear(year) 13 | { 14 | 15 | } 16 | 17 | std::string Automobile::getManufacturer() 18 | { 19 | return mManufacturer; 20 | } 21 | 22 | void Automobile::setManufacturer(std::string manufacturer) 23 | { 24 | mManufacturer = manufacturer; 25 | } 26 | 27 | std::string Automobile::getModel() 28 | { 29 | return mModel; 30 | } 31 | 32 | void Automobile::setModel(std::string model) 33 | { 34 | mModel = model; 35 | } 36 | 37 | int Automobile::getYear() 38 | { 39 | return mYear; 40 | } 41 | 42 | void Automobile::setYear(int year) 43 | { 44 | mYear = year; 45 | } 46 | 47 | 48 | void Automobile::getDescription() 49 | { 50 | std::cout << mYear << " " << mManufacturer << " " << mModel << std::endl; 51 | } 52 | 53 | int Automobile::getAge() 54 | { 55 | time_t t = time(0); 56 | struct tm* now = localtime(&t); 57 | 58 | return (now->tm_year + 1900) - mYear; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Exercises-5-1-and-5-2/Automobile.h: -------------------------------------------------------------------------------- 1 | #ifndef AUTOMOBILE_H 2 | #define AUTOMOBILE_H 3 | 4 | #include 5 | 6 | class Automobile 7 | { 8 | public: 9 | Automobile(); 10 | Automobile(std::string manufacturer, std::string model, int year); 11 | std::string getManufacturer(); 12 | void setManufacturer(std::string manufacturer); 13 | std::string getModel(); 14 | void setModel(std::string model); 15 | int getYear(); 16 | void setYear(int year); 17 | void getDescription(); 18 | int getAge(); 19 | 20 | private: 21 | std::string mManufacturer; 22 | std::string mModel; 23 | int mYear; 24 | }; 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Exercises-5-1-and-5-2/Exercise-5-1-and-5-2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 5-1 3 | * 4 | * Let's try implementing a class using the basic framework. Consider a class to 5 | * store the data for an automobile. We'll have three pieces of data: a manufacturer 6 | * name and model name, both strings, and a model year, an integer. Create a class 7 | * with get/set methods for each data member. Make sure you make good decisions 8 | * concerning details like member names. It's not important that you follow my 9 | * particular naming conventions. What's important is that you think about the 10 | * choices you make and are consistent in your decisions 11 | * 12 | * Exercise 5-2 13 | * 14 | * For our automobile class from the previous exercise, add a support method that 15 | * returns a complete description of the automobile object as a formatted string, 16 | * such as, "1957 Chevrolet Impala". Add a second support method that returns 17 | * the age of the automobile in years. 18 | */ 19 | 20 | #include 21 | #include "Automobile.h" 22 | 23 | int main() 24 | { 25 | Automobile jeep("Jeep", "Cherokee", 1993); 26 | 27 | jeep.getDescription(); 28 | 29 | std::cout << "Car age = " << jeep.getAge() << "." << std::endl; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Unkown-Student-Records/Unkown-Student-Records.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Tracking an Unknown Quantity of Student Records 3 | * 4 | * In this problem, you will write a class with methods to store and 5 | * manipulate a collection of student records. A student record contains 6 | * a student number and a grade, both integers, and a string for the student 7 | * name. The following functions are to be implemented: 8 | * 9 | * addRecord - This method takes a student number, name, and grade and adds 10 | * a new record with this data to the collection. 11 | * 12 | * recordWithNumber - This function takes a student number and retrieves the 13 | * record with that student number from the collection. 14 | * 15 | * removeRecord - This function takes a student number and removes the record 16 | * with that student number from the collection. 17 | * 18 | * The collection can be of any size. The addRecord operation is expected to 19 | * be called frequently, so it must be implemented efficiently. 20 | */ 21 | 22 | #include 23 | #include "studentRecord.h" 24 | #include "studentCollection.h" 25 | 26 | int main() 27 | { 28 | studentCollection s; 29 | 30 | studentRecord stu3(84, 1152, "Sue"); 31 | studentRecord stu2(75, 4875, "Ed"); 32 | studentRecord stu1(98, 2938, "Todd"); 33 | 34 | s.addRecord(stu3); 35 | s.addRecord(stu2); 36 | s.addRecord(stu1); 37 | 38 | std::cout << "Student 2: " << s.recordWithNumber(4875).name() << " " << std::endl; 39 | std::cout << "Removing student 2" << std::endl; 40 | 41 | s.removeRecord(4875); 42 | 43 | std::cout << "Student 2: " << s.recordWithNumber(4875).name() << " " << std::endl; 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Unkown-Student-Records/studentCollection.cpp: -------------------------------------------------------------------------------- 1 | #include "studentCollection.h" 2 | #include "studentRecord.h" 3 | 4 | studentCollection::studentCollection() 5 | { 6 | _listHead = NULL; 7 | } 8 | 9 | studentCollection::studentCollection(const studentCollection& original) 10 | { 11 | _listHead = copiedList(original._listHead); 12 | } 13 | 14 | studentCollection::~studentCollection() 15 | { 16 | deleteList(_listHead); 17 | } 18 | void studentCollection::addRecord(studentRecord newStudent) 19 | { 20 | studentNode* newNode = new studentNode; 21 | newNode->studentData = newStudent; 22 | newNode->next = _listHead; 23 | _listHead = newNode; 24 | } 25 | 26 | studentRecord studentCollection::recordWithNumber(int idNum) 27 | { 28 | studentNode* loopPtr = _listHead; 29 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 30 | { 31 | loopPtr = loopPtr->next; 32 | } 33 | 34 | if (loopPtr == NULL) 35 | { 36 | studentRecord dummyRecord(-1, -1, ""); 37 | return dummyRecord; 38 | } 39 | else 40 | { 41 | return loopPtr->studentData; 42 | } 43 | } 44 | 45 | void studentCollection::removeRecord(int idNum) 46 | { 47 | studentNode* loopPtr = _listHead; 48 | studentNode* trailing = NULL; 49 | 50 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 51 | { 52 | trailing = loopPtr; 53 | loopPtr = loopPtr->next; 54 | } 55 | 56 | if (loopPtr == NULL) return; 57 | 58 | if (trailing == NULL) 59 | { 60 | _listHead = _listHead->next; 61 | } 62 | else 63 | { 64 | trailing->next = loopPtr->next; 65 | } 66 | 67 | delete loopPtr; 68 | } 69 | 70 | void studentCollection::deleteList(studentList &listPtr) 71 | { 72 | while (listPtr != NULL) 73 | { 74 | studentNode* temp = listPtr; 75 | listPtr = listPtr->next; 76 | delete temp; 77 | } 78 | } 79 | 80 | studentCollection::studentList studentCollection::copiedList(const studentList original) 81 | { 82 | if (original == NULL) 83 | { 84 | return NULL; 85 | } 86 | 87 | studentList newList = new studentNode; 88 | newList->studentData = original->studentData; 89 | studentNode* oldLoopPtr = original->next; 90 | studentNode* newLoopPtr = newList; 91 | 92 | while (oldLoopPtr != NULL) 93 | { 94 | 95 | newLoopPtr->next = new studentNode; 96 | newLoopPtr = newList->next; 97 | newLoopPtr->studentData = oldLoopPtr->studentData; 98 | oldLoopPtr = oldLoopPtr->next; 99 | } 100 | newLoopPtr->next = NULL; 101 | return newList; 102 | } 103 | 104 | studentCollection& studentCollection::operator=(const studentCollection& rhs) 105 | { 106 | if (this != &rhs) 107 | { 108 | deleteList(_listHead); 109 | _listHead = copiedList(rhs._listHead); 110 | } 111 | return *this; 112 | } 113 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Unkown-Student-Records/studentCollection.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTCOLLECTION_H 2 | #define STUDENTCOLLECTION_H 3 | 4 | #include "studentRecord.h" 5 | 6 | class studentCollection 7 | { 8 | private: 9 | struct studentNode 10 | { 11 | studentRecord studentData; 12 | studentNode* next; 13 | }; 14 | public: 15 | studentCollection(); 16 | studentCollection(const studentCollection& original); 17 | ~studentCollection(); 18 | studentCollection& operator=(const studentCollection& rhs); 19 | void addRecord(studentRecord newStudent); 20 | studentRecord recordWithNumber(int idNum); 21 | void removeRecord(int idNum); 22 | private: 23 | typedef studentNode* studentList; 24 | studentList _listHead; 25 | void deleteList(studentList &listPtr); 26 | studentList copiedList(const studentList original); 27 | }; 28 | 29 | #endif // STUDENTCOLLECTION_H 30 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Unkown-Student-Records/studentRecord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentRecord.h" 3 | 4 | studentRecord::studentRecord() 5 | { 6 | setGrade(0); 7 | setStudentID(-1); 8 | setName(""); 9 | } 10 | 11 | studentRecord::studentRecord(int newGrade, int newID, std::string newName) 12 | { 13 | setGrade(newGrade); 14 | setStudentID(newID); 15 | setName(newName); 16 | } 17 | 18 | int studentRecord::grade() 19 | { 20 | return _grade; 21 | } 22 | 23 | bool studentRecord::isValidGrade(int grade) 24 | { 25 | if ((grade >= 0) && (grade <= 100)) 26 | { 27 | return true; 28 | } 29 | else 30 | { 31 | return false; 32 | } 33 | } 34 | 35 | 36 | void studentRecord::setGrade(int newGrade) 37 | { 38 | if (isValidGrade(newGrade)) 39 | { 40 | _grade = newGrade; 41 | } 42 | } 43 | 44 | int studentRecord::studentID() 45 | { 46 | return _studentID; 47 | } 48 | 49 | void studentRecord::setStudentID(int newID) 50 | { 51 | _studentID = newID; 52 | } 53 | 54 | 55 | std::string studentRecord::name() 56 | { 57 | return _name; 58 | } 59 | 60 | void studentRecord::setName(std::string newName) 61 | { 62 | _name = newName; 63 | } 64 | 65 | std::string studentRecord::letterGrade() 66 | { 67 | if(!isValidGrade(_grade)) return "ERROR"; 68 | 69 | const int NUMBER_CATEGORIES = 11; 70 | const std::string GRADE_LETTER[NUMBER_CATEGORIES] = { "F", "D", "D+", "C-", 71 | "C", "C+", "B-", "B", "B+", "A-", "A" }; 72 | const int LOWEST_GRADE_SCORE[NUMBER_CATEGORIES] = { 0, 60, 67, 70, 73, 77, 73 | 80, 83, 87, 90, 93 }; 74 | 75 | int category = 0; 76 | while (category < NUMBER_CATEGORIES && LOWEST_GRADE_SCORE[category] <= _grade) 77 | { 78 | category++; 79 | } 80 | return GRADE_LETTER[category - 1]; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Chapter-5-Exercises/Unkown-Student-Records/studentRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTRECORD_H 2 | #define STUDENTRECORD_H 3 | 4 | #include 5 | 6 | class studentRecord 7 | { 8 | public: 9 | studentRecord(); 10 | studentRecord(int newGrade, int newID, std::string newName); 11 | int grade(); 12 | bool isValidGrade(int grade); 13 | void setGrade(int newGrade); 14 | int studentID(); 15 | void setStudentID(int newID); 16 | std::string name(); 17 | void setName(std::string newName); 18 | std::string letterGrade(); 19 | private: 20 | int _grade; 21 | int _studentID; 22 | std::string _name; 23 | }; 24 | 25 | #endif // STUDENTRECORD_H 26 | -------------------------------------------------------------------------------- /Chapter-6-Exercises/Computing-the-Sum-of-an-Integer-Array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Computing the Sum of an Array of Integers 3 | * 4 | * Write a recursive function that is given an array of integers and the size 5 | * of the array as parameters. The function returns the sum of the integers 6 | * in the array. 7 | */ 8 | 9 | #include 10 | 11 | int iterativeArraySum(int integers[], int size); 12 | 13 | int arraySumDelegate(int integers[], int size); 14 | 15 | int arraySumRecursive(int integers[], int size); 16 | 17 | int main() 18 | { 19 | int size = 10; 20 | int numbers[size] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 21 | 22 | std::cout << "Iterative Approach" << std::endl; 23 | std::cout << "sum = " << iterativeArraySum(numbers, size) << std::endl << std::endl; 24 | 25 | std::cout << "Dispatcher Function" << std::endl; 26 | std::cout << "sum = " << arraySumDelegate(numbers, size) << std::endl << std::endl; 27 | 28 | std::cout << "Recursive Approach" << std::endl; 29 | std::cout << "sum = " << arraySumRecursive(numbers, size) << std::endl << std::endl; 30 | 31 | return 0; 32 | } 33 | 34 | int iterativeArraySum(int integers[], int size) 35 | { 36 | int sum = 0; 37 | for (int i = 0; i < size; i++) 38 | { 39 | sum += integers[i]; 40 | } 41 | return sum; 42 | } 43 | 44 | int arraySumDelegate(int integers[], int size) 45 | { 46 | if (size == 0) return 0; 47 | int lastNumber = integers[size - 1]; 48 | int allButLastSum = iterativeArraySum(integers, size - 1); 49 | return lastNumber + allButLastSum; 50 | } 51 | 52 | int arraySumRecursive(int integers[], int size) 53 | { 54 | if (size == 0) return 0; 55 | int lastNumber = integers[size - 1]; 56 | int allButLastSum = arraySumRecursive(integers, size - 1); 57 | return lastNumber + allButLastSum; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter-6-Exercises/Counting-Negative-Numbers-in-a-Singly-Linked-List.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Counting Negative Numbers in a Singly Linked List 3 | * 4 | * Write a recursive function that is given a singly linked list where the data 5 | * type is integer. The function returns the count of negative numbers in the 6 | * list. 7 | */ 8 | 9 | #include 10 | 11 | struct exListNode 12 | { 13 | int data; 14 | exListNode* next; 15 | }; 16 | 17 | typedef exListNode* listPtr; 18 | 19 | int countNegative(listPtr head); 20 | 21 | int main() 22 | { 23 | listPtr numbers; 24 | 25 | exListNode* node1 = new exListNode; 26 | node1->data = -1; 27 | 28 | exListNode* node2 = new exListNode; 29 | node1->data = -1; 30 | 31 | exListNode* node3 = new exListNode; 32 | node1->data = -1; 33 | 34 | exListNode* node4 = new exListNode; 35 | node1->data = 1; 36 | 37 | numbers = node1; 38 | node1->next = node2; 39 | node2->next = node3; 40 | node3->next = node4; 41 | node4->next = NULL; 42 | 43 | node1 = node2 = node3 = node4 = NULL; 44 | 45 | int negativeCount = countNegative(numbers); 46 | 47 | std::cout << "Count = " << negativeCount << std::endl; 48 | 49 | return 0; 50 | } 51 | 52 | int countNegative(listPtr head) 53 | { 54 | if (head == NULL) return 0; 55 | int listCount = countNegative(head->next); 56 | if (head->data < 0) listCount++; 57 | return listCount; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter-6-Exercises/Exercise-6-1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Exercise 6.1 3 | * 4 | * Write a function to compute the sum of just the positive numbers in an array 5 | * of integers. First, solve the problem using iteration. Then, using the tecnique 6 | * shown in this chapter, convert your iterative function to a recursive function. 7 | */ 8 | 9 | #include 10 | 11 | int IterativePositiveSum(int numArray[], int arraySize); 12 | int RecursivePositiveSum(int numArray[], int arraySize); 13 | 14 | int main() 15 | { 16 | int numbers[] = {1, -1, 1, -1, 1, 1, -1}; 17 | 18 | std::cout << "Iterative Sum = " << IterativePositiveSum(numbers, 7) << std::endl; 19 | 20 | std::cout << "Recursive Sum = " << RecursivePositiveSum(numbers, 7) << std::endl; 21 | 22 | return 0; 23 | } 24 | 25 | int IterativePositiveSum(int numArray[], int arraySize) 26 | { 27 | int result = 0; 28 | for(int i = 0; i < arraySize; i++) 29 | { 30 | if (numArray[i] > 0) 31 | { 32 | result += numArray[i]; 33 | } 34 | } 35 | return result; 36 | } 37 | 38 | int RecursivePositiveSum(int numArray[], int arraySize) 39 | { 40 | if (arraySize == 0) return 0; 41 | int lastNum = 0; 42 | if (numArray[arraySize - 1] > 0) lastNum = numArray[arraySize - 1]; 43 | int allButLastSum = RecursivePositiveSum(numArray, arraySize - 1); 44 | return lastNum + allButLastSum; 45 | } 46 | -------------------------------------------------------------------------------- /Chapter-6-Exercises/Find-the-Largest-Value-in-a-Binary-Tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Find the largest value in a binary tree 3 | * 4 | * Write a function that, when given a binary tree where each node holds an integer, 5 | * returns the largest integer in the tree. 6 | */ 7 | 8 | #include 9 | 10 | struct treeNode 11 | { 12 | int data; 13 | treeNode* left; 14 | treeNode* right; 15 | }; 16 | 17 | typedef treeNode* treePtr; 18 | 19 | int maxValue(treePtr root); 20 | 21 | int main() 22 | { 23 | 24 | } 25 | 26 | int maxValue(treePtr root) 27 | { 28 | if (root = NULL) return 0; 29 | if (root->right == NULL && root->left == NULL) 30 | { 31 | return root->data; 32 | } 33 | int leftMax = maxValue(root->left); 34 | int rightMax = maxValue(root->right); 35 | int maxNum = root->data; 36 | if (leftMax > maxNum) maxNum = leftMax; 37 | if (rightMax > maxNum) maxNum = rightMax; 38 | return maxNum; 39 | } 40 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/Efficient-Traversal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: Efficient Traversal 3 | * 4 | * A programming project will use your studentCollection class. The client code 5 | * needs the ability to traverse all of the students in the collection. Obviously, 6 | * to maintain information hiding, the client code cannot be given direct access 7 | * to the list, but it's a requirement that the traversals are efficient. 8 | */ 9 | 10 | #include 11 | #include 12 | #include "studentCollection.h" 13 | #include "studentRecord.h" 14 | #include "scIterator.h" 15 | 16 | int main() 17 | { 18 | 19 | // create some student records 20 | studentRecord Tom(97, 1, "Tom"); 21 | studentRecord Holly(98, 2, "Holly"); 22 | studentRecord Sophie(100, 3, "Sophie"); 23 | studentRecord Wrigley(93, 4, "Wrigley"); 24 | 25 | // create collection and add records 26 | studentCollection Collection; 27 | Collection.addRecord(Tom); 28 | Collection.addRecord(Holly); 29 | Collection.addRecord(Sophie); 30 | Collection.addRecord(Wrigley); 31 | 32 | scIterator iter; 33 | int gradeTotal = 0; 34 | int numRecords = 0; 35 | 36 | iter = Collection.firstItemIterator(); 37 | while (!iter.pastEnd()) 38 | { 39 | numRecords++; 40 | gradeTotal += iter.student().grade(); 41 | iter.advance(); 42 | } 43 | 44 | double average = (double) gradeTotal / numRecords; 45 | 46 | std::cout << "Average grade is " << average << std::endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/scIterator.cpp: -------------------------------------------------------------------------------- 1 | #include "scIterator.h" 2 | #include "studentCollection.h" 3 | #include "studentRecord.h" 4 | 5 | scIterator::scIterator() 6 | { 7 | current = NULL; 8 | } 9 | scIterator::scIterator(studentCollection::studentNode* initial) 10 | { 11 | current = initial; 12 | } 13 | 14 | scIterator studentCollection::firstItemIterator() 15 | { 16 | return scIterator(_listHead); 17 | } 18 | 19 | void scIterator::advance() 20 | { 21 | if (current != NULL) 22 | { 23 | current = current->next; 24 | } 25 | } 26 | 27 | bool scIterator::pastEnd() 28 | { 29 | return current == NULL; 30 | } 31 | 32 | studentRecord scIterator::student() 33 | { 34 | if (current == NULL) 35 | { 36 | studentRecord dummyRecord(-1, -1, ""); 37 | return dummyRecord; 38 | } 39 | else 40 | { 41 | return current->studentData; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/scIterator.h: -------------------------------------------------------------------------------- 1 | #ifndef SCITERATOR_H 2 | #define SCITERATOR_H 3 | 4 | #include "studentRecord.h" 5 | #include "studentCollection.h" 6 | 7 | class studentCollection; 8 | 9 | class scIterator 10 | { 11 | public: 12 | scIterator(); 13 | // compiler raises error here 14 | // expected ')' before '*' token 15 | scIterator(studentCollection::studentNode* initial); 16 | void advance(); 17 | bool pastEnd(); 18 | studentRecord student(); 19 | private: 20 | // compiler raises error here 21 | // 'studentNode' in 'class studentCollection' does not name a type 22 | studentCollection::studentNode* current; 23 | }; 24 | 25 | #endif // SCITERATOR_H 26 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/studentCollection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentCollection.h" 3 | #include "studentRecord.h" 4 | 5 | bool higherGrade(studentRecord r1, studentRecord r2) 6 | { 7 | return r1.grade() > r2.grade(); 8 | } 9 | 10 | bool lowerStudentNumber(studentRecord r1, studentRecord r2) 11 | { 12 | return r1.studentID() < r2.studentID(); 13 | } 14 | 15 | bool nameComesFirst(studentRecord r1, studentRecord r2) 16 | { 17 | return strcmp(r1.name().c_str(), r2.name().c_str()) < 0; 18 | } 19 | 20 | 21 | studentCollection::studentCollection() 22 | { 23 | _listHead = NULL; 24 | _currentPolicy = NULL; 25 | } 26 | 27 | studentCollection::studentCollection(const studentCollection& original) 28 | { 29 | _listHead = copiedList(original._listHead); 30 | } 31 | 32 | studentCollection::~studentCollection() 33 | { 34 | deleteList(_listHead); 35 | } 36 | void studentCollection::addRecord(studentRecord newStudent) 37 | { 38 | studentNode* newNode = new studentNode; 39 | newNode->studentData = newStudent; 40 | newNode->next = _listHead; 41 | _listHead = newNode; 42 | } 43 | 44 | studentRecord studentCollection::recordWithNumber(int idNum) 45 | { 46 | studentNode* loopPtr = _listHead; 47 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 48 | { 49 | loopPtr = loopPtr->next; 50 | } 51 | 52 | if (loopPtr == NULL) 53 | { 54 | studentRecord dummyRecord(-1, -1, ""); 55 | return dummyRecord; 56 | } 57 | else 58 | { 59 | return loopPtr->studentData; 60 | } 61 | } 62 | 63 | void studentCollection::removeRecord(int idNum) 64 | { 65 | studentNode* loopPtr = _listHead; 66 | studentNode* trailing = NULL; 67 | 68 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 69 | { 70 | trailing = loopPtr; 71 | loopPtr = loopPtr->next; 72 | } 73 | 74 | if (loopPtr == NULL) return; 75 | 76 | if (trailing == NULL) 77 | { 78 | _listHead = _listHead->next; 79 | } 80 | else 81 | { 82 | trailing->next = loopPtr->next; 83 | } 84 | 85 | delete loopPtr; 86 | } 87 | 88 | void studentCollection::setFirstStudentPolicy(firstStudentPolicy f) 89 | { 90 | _currentPolicy = f; 91 | } 92 | 93 | studentRecord studentCollection::firstStudent() 94 | { 95 | if (_listHead == NULL || _currentPolicy == NULL) 96 | { 97 | studentRecord dummyRecord(-1, -1, ""); 98 | return dummyRecord; 99 | } 100 | studentNode* loopPtr = _listHead; 101 | studentRecord first = loopPtr->studentData; 102 | loopPtr = loopPtr->next; 103 | while (loopPtr != NULL) 104 | { 105 | if (_currentPolicy(loopPtr->studentData, first)) 106 | { 107 | first = loopPtr->studentData; 108 | } 109 | loopPtr = loopPtr->next; 110 | } 111 | return first; 112 | } 113 | 114 | void studentCollection::deleteList(studentList &listPtr) 115 | { 116 | while (listPtr != NULL) 117 | { 118 | studentNode* temp = listPtr; 119 | listPtr = listPtr->next; 120 | delete temp; 121 | } 122 | } 123 | 124 | studentCollection::studentList studentCollection::copiedList(const studentList original) 125 | { 126 | if (original == NULL) 127 | { 128 | return NULL; 129 | } 130 | 131 | studentList newList = new studentNode; 132 | newList->studentData = original->studentData; 133 | studentNode* oldLoopPtr = original->next; 134 | studentNode* newLoopPtr = newList; 135 | 136 | while (oldLoopPtr != NULL) 137 | { 138 | 139 | newLoopPtr->next = new studentNode; 140 | newLoopPtr = newList->next; 141 | newLoopPtr->studentData = oldLoopPtr->studentData; 142 | oldLoopPtr = oldLoopPtr->next; 143 | } 144 | newLoopPtr->next = NULL; 145 | return newList; 146 | } 147 | 148 | studentCollection& studentCollection::operator=(const studentCollection& rhs) 149 | { 150 | if (this != &rhs) 151 | { 152 | deleteList(_listHead); 153 | _listHead = copiedList(rhs._listHead); 154 | } 155 | return *this; 156 | } 157 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/studentCollection.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTCOLLECTION_H 2 | #define STUDENTCOLLECTION_H 3 | 4 | #include "studentRecord.h" 5 | #include "scIterator.h" 6 | 7 | typedef bool (* firstStudentPolicy)(studentRecord r1, studentRecord r2); 8 | 9 | bool higherGrade(studentRecord r1, studentRecord r2); 10 | bool lowerStudentNumber(studentRecord r1, studentRecord r2); 11 | bool nameComesFirst(studentRecord r1, studentRecord r2); 12 | 13 | class studentCollection 14 | { 15 | private: 16 | struct studentNode 17 | { 18 | studentRecord studentData; 19 | studentNode* next; 20 | }; 21 | public: 22 | studentCollection(); 23 | studentCollection(const studentCollection& original); 24 | ~studentCollection(); 25 | studentCollection& operator=(const studentCollection& rhs); 26 | void addRecord(studentRecord newStudent); 27 | studentRecord recordWithNumber(int idNum); 28 | void removeRecord(int idNum); 29 | void setFirstStudentPolicy(firstStudentPolicy f); 30 | studentRecord firstStudent(); 31 | friend class scIterator; 32 | scIterator firstItemIterator(); 33 | private: 34 | firstStudentPolicy _currentPolicy; 35 | typedef studentNode* studentList; 36 | studentList _listHead; 37 | void deleteList(studentList &listPtr); 38 | studentList copiedList(const studentList original); 39 | }; 40 | 41 | 42 | 43 | #endif // STUDENTCOLLECTION_H 44 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/studentRecord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentRecord.h" 3 | 4 | studentRecord::studentRecord() 5 | { 6 | setGrade(0); 7 | setStudentID(-1); 8 | setName(""); 9 | } 10 | 11 | studentRecord::studentRecord(int newGrade, int newID, std::string newName) 12 | { 13 | setGrade(newGrade); 14 | setStudentID(newID); 15 | setName(newName); 16 | } 17 | 18 | int studentRecord::grade() 19 | { 20 | return _grade; 21 | } 22 | 23 | bool studentRecord::isValidGrade(int grade) 24 | { 25 | if ((grade >= 0) && (grade <= 100)) 26 | { 27 | return true; 28 | } 29 | else 30 | { 31 | return false; 32 | } 33 | } 34 | 35 | 36 | void studentRecord::setGrade(int newGrade) 37 | { 38 | if (isValidGrade(newGrade)) 39 | { 40 | _grade = newGrade; 41 | } 42 | } 43 | 44 | int studentRecord::studentID() 45 | { 46 | return _studentID; 47 | } 48 | 49 | void studentRecord::setStudentID(int newID) 50 | { 51 | _studentID = newID; 52 | } 53 | 54 | 55 | std::string studentRecord::name() 56 | { 57 | return _name; 58 | } 59 | 60 | void studentRecord::setName(std::string newName) 61 | { 62 | _name = newName; 63 | } 64 | 65 | std::string studentRecord::letterGrade() 66 | { 67 | if(!isValidGrade(_grade)) return "ERROR"; 68 | 69 | const int NUMBER_CATEGORIES = 11; 70 | const std::string GRADE_LETTER[NUMBER_CATEGORIES] = { "F", "D", "D+", "C-", 71 | "C", "C+", "B-", "B", "B+", "A-", "A" }; 72 | const int LOWEST_GRADE_SCORE[NUMBER_CATEGORIES] = { 0, 60, 67, 70, 73, 77, 73 | 80, 83, 87, 90, 93 }; 74 | 75 | int category = 0; 76 | while (category < NUMBER_CATEGORIES && LOWEST_GRADE_SCORE[category] <= _grade) 77 | { 78 | category++; 79 | } 80 | return GRADE_LETTER[category - 1]; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/Efficient-Traversal/studentRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTRECORD_H 2 | #define STUDENTRECORD_H 3 | 4 | #include 5 | 6 | class studentRecord 7 | { 8 | public: 9 | studentRecord(); 10 | studentRecord(int newGrade, int newID, std::string newName); 11 | int grade(); 12 | bool isValidGrade(int grade); 13 | void setGrade(int newGrade); 14 | int studentID(); 15 | void setStudentID(int newID); 16 | std::string name(); 17 | void setName(std::string newName); 18 | std::string letterGrade(); 19 | private: 20 | int _grade; 21 | int _studentID; 22 | std::string _name; 23 | }; 24 | 25 | #endif // STUDENTRECORD_H 26 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/The-First-Student/The-First-Student.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem: The First Student 3 | * 4 | * At a particular school, each class has a designated "first student" who is 5 | * responsible for maintaining order in the classroom if the teacher has to 6 | * leave the room. Originally, this title was bestowed upon the student with the 7 | * highest grade, but now some teachers thing the first student should be the 8 | * student with the greatest seniority, which means the lowest student ID number, 9 | * as they are assigned sequentially. Another faction of teachers thinks the 10 | * first student tradition is silly and intends to protest by simply choosing the 11 | * student whose name appears first in the alphabetical class roll. Our task is to 12 | * modify the student collection class, adding a method to retrieve the first 13 | * student from the collection, while accommodating the selection criteria of the 14 | * various teacher groups. 15 | */ 16 | 17 | #include 18 | #include 19 | #include "studentCollection.h" 20 | #include "studentRecord.h" 21 | 22 | int main() 23 | { 24 | // create some student records 25 | studentRecord Tom(97, 1, "Tom"); 26 | studentRecord Holly(98, 2, "Holly"); 27 | studentRecord Sophie(100, 3, "Sophie"); 28 | studentRecord Wrigley(93, 4, "Wrigley"); 29 | 30 | // create collection and add records 31 | studentCollection Collection; 32 | Collection.addRecord(Tom); 33 | Collection.addRecord(Holly); 34 | Collection.addRecord(Sophie); 35 | Collection.addRecord(Wrigley); 36 | 37 | // change the policy and output results 38 | Collection.setFirstStudentPolicy(higherGrade); 39 | std::cout << "First Student by Highest Grade" << std::endl; 40 | std::cout << Collection.firstStudent().name() << std::endl << std::endl; 41 | 42 | Collection.setFirstStudentPolicy(lowerStudentNumber); 43 | std::cout << "First Student by Lowest Student Number" << std::endl; 44 | std::cout << Collection.firstStudent().name() << std::endl << std::endl; 45 | 46 | Collection.setFirstStudentPolicy(nameComesFirst); 47 | std::cout << "First Student by Name" << std::endl; 48 | std::cout << Collection.firstStudent().name() << std::endl << std::endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/The-First-Student/studentCollection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentCollection.h" 3 | #include "studentRecord.h" 4 | 5 | bool higherGrade(studentRecord r1, studentRecord r2) 6 | { 7 | return r1.grade() > r2.grade(); 8 | } 9 | 10 | bool lowerStudentNumber(studentRecord r1, studentRecord r2) 11 | { 12 | return r1.studentID() < r2.studentID(); 13 | } 14 | 15 | bool nameComesFirst(studentRecord r1, studentRecord r2) 16 | { 17 | return strcmp(r1.name().c_str(), r2.name().c_str()) < 0; 18 | } 19 | 20 | 21 | studentCollection::studentCollection() 22 | { 23 | _listHead = NULL; 24 | _currentPolicy = NULL; 25 | } 26 | 27 | studentCollection::studentCollection(const studentCollection& original) 28 | { 29 | _listHead = copiedList(original._listHead); 30 | } 31 | 32 | studentCollection::~studentCollection() 33 | { 34 | deleteList(_listHead); 35 | } 36 | void studentCollection::addRecord(studentRecord newStudent) 37 | { 38 | studentNode* newNode = new studentNode; 39 | newNode->studentData = newStudent; 40 | newNode->next = _listHead; 41 | _listHead = newNode; 42 | } 43 | 44 | studentRecord studentCollection::recordWithNumber(int idNum) 45 | { 46 | studentNode* loopPtr = _listHead; 47 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 48 | { 49 | loopPtr = loopPtr->next; 50 | } 51 | 52 | if (loopPtr == NULL) 53 | { 54 | studentRecord dummyRecord(-1, -1, ""); 55 | return dummyRecord; 56 | } 57 | else 58 | { 59 | return loopPtr->studentData; 60 | } 61 | } 62 | 63 | void studentCollection::removeRecord(int idNum) 64 | { 65 | studentNode* loopPtr = _listHead; 66 | studentNode* trailing = NULL; 67 | 68 | while (loopPtr != NULL && loopPtr->studentData.studentID() != idNum) 69 | { 70 | trailing = loopPtr; 71 | loopPtr = loopPtr->next; 72 | } 73 | 74 | if (loopPtr == NULL) return; 75 | 76 | if (trailing == NULL) 77 | { 78 | _listHead = _listHead->next; 79 | } 80 | else 81 | { 82 | trailing->next = loopPtr->next; 83 | } 84 | 85 | delete loopPtr; 86 | } 87 | 88 | void studentCollection::setFirstStudentPolicy(firstStudentPolicy f) 89 | { 90 | _currentPolicy = f; 91 | } 92 | 93 | studentRecord studentCollection::firstStudent() 94 | { 95 | if (_listHead == NULL || _currentPolicy == NULL) 96 | { 97 | studentRecord dummyRecord(-1, -1, ""); 98 | return dummyRecord; 99 | } 100 | studentNode* loopPtr = _listHead; 101 | studentRecord first = loopPtr->studentData; 102 | loopPtr = loopPtr->next; 103 | while (loopPtr != NULL) 104 | { 105 | if (_currentPolicy(loopPtr->studentData, first)) 106 | { 107 | first = loopPtr->studentData; 108 | } 109 | loopPtr = loopPtr->next; 110 | } 111 | return first; 112 | } 113 | 114 | void studentCollection::deleteList(studentList &listPtr) 115 | { 116 | while (listPtr != NULL) 117 | { 118 | studentNode* temp = listPtr; 119 | listPtr = listPtr->next; 120 | delete temp; 121 | } 122 | } 123 | 124 | studentCollection::studentList studentCollection::copiedList(const studentList original) 125 | { 126 | if (original == NULL) 127 | { 128 | return NULL; 129 | } 130 | 131 | studentList newList = new studentNode; 132 | newList->studentData = original->studentData; 133 | studentNode* oldLoopPtr = original->next; 134 | studentNode* newLoopPtr = newList; 135 | 136 | while (oldLoopPtr != NULL) 137 | { 138 | 139 | newLoopPtr->next = new studentNode; 140 | newLoopPtr = newList->next; 141 | newLoopPtr->studentData = oldLoopPtr->studentData; 142 | oldLoopPtr = oldLoopPtr->next; 143 | } 144 | newLoopPtr->next = NULL; 145 | return newList; 146 | } 147 | 148 | studentCollection& studentCollection::operator=(const studentCollection& rhs) 149 | { 150 | if (this != &rhs) 151 | { 152 | deleteList(_listHead); 153 | _listHead = copiedList(rhs._listHead); 154 | } 155 | return *this; 156 | } 157 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/The-First-Student/studentCollection.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTCOLLECTION_H 2 | #define STUDENTCOLLECTION_H 3 | 4 | #include "studentRecord.h" 5 | 6 | typedef bool (* firstStudentPolicy)(studentRecord r1, studentRecord r2); 7 | 8 | bool higherGrade(studentRecord r1, studentRecord r2); 9 | bool lowerStudentNumber(studentRecord r1, studentRecord r2); 10 | bool nameComesFirst(studentRecord r1, studentRecord r2); 11 | 12 | 13 | class studentCollection 14 | { 15 | private: 16 | struct studentNode 17 | { 18 | studentRecord studentData; 19 | studentNode* next; 20 | }; 21 | public: 22 | studentCollection(); 23 | studentCollection(const studentCollection& original); 24 | ~studentCollection(); 25 | studentCollection& operator=(const studentCollection& rhs); 26 | void addRecord(studentRecord newStudent); 27 | studentRecord recordWithNumber(int idNum); 28 | void removeRecord(int idNum); 29 | void setFirstStudentPolicy(firstStudentPolicy f); 30 | studentRecord firstStudent(); 31 | private: 32 | firstStudentPolicy _currentPolicy; 33 | typedef studentNode* studentList; 34 | studentList _listHead; 35 | void deleteList(studentList &listPtr); 36 | studentList copiedList(const studentList original); 37 | }; 38 | 39 | 40 | 41 | #endif // STUDENTCOLLECTION_H 42 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/The-First-Student/studentRecord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "studentRecord.h" 3 | 4 | studentRecord::studentRecord() 5 | { 6 | setGrade(0); 7 | setStudentID(-1); 8 | setName(""); 9 | } 10 | 11 | studentRecord::studentRecord(int newGrade, int newID, std::string newName) 12 | { 13 | setGrade(newGrade); 14 | setStudentID(newID); 15 | setName(newName); 16 | } 17 | 18 | int studentRecord::grade() 19 | { 20 | return _grade; 21 | } 22 | 23 | bool studentRecord::isValidGrade(int grade) 24 | { 25 | if ((grade >= 0) && (grade <= 100)) 26 | { 27 | return true; 28 | } 29 | else 30 | { 31 | return false; 32 | } 33 | } 34 | 35 | 36 | void studentRecord::setGrade(int newGrade) 37 | { 38 | if (isValidGrade(newGrade)) 39 | { 40 | _grade = newGrade; 41 | } 42 | } 43 | 44 | int studentRecord::studentID() 45 | { 46 | return _studentID; 47 | } 48 | 49 | void studentRecord::setStudentID(int newID) 50 | { 51 | _studentID = newID; 52 | } 53 | 54 | 55 | std::string studentRecord::name() 56 | { 57 | return _name; 58 | } 59 | 60 | void studentRecord::setName(std::string newName) 61 | { 62 | _name = newName; 63 | } 64 | 65 | std::string studentRecord::letterGrade() 66 | { 67 | if(!isValidGrade(_grade)) return "ERROR"; 68 | 69 | const int NUMBER_CATEGORIES = 11; 70 | const std::string GRADE_LETTER[NUMBER_CATEGORIES] = { "F", "D", "D+", "C-", 71 | "C", "C+", "B-", "B", "B+", "A-", "A" }; 72 | const int LOWEST_GRADE_SCORE[NUMBER_CATEGORIES] = { 0, 60, 67, 70, 73, 77, 73 | 80, 83, 87, 90, 93 }; 74 | 75 | int category = 0; 76 | while (category < NUMBER_CATEGORIES && LOWEST_GRADE_SCORE[category] <= _grade) 77 | { 78 | category++; 79 | } 80 | return GRADE_LETTER[category - 1]; 81 | } 82 | 83 | -------------------------------------------------------------------------------- /Chapter-7-Exercises/The-First-Student/studentRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef STUDENTRECORD_H 2 | #define STUDENTRECORD_H 3 | 4 | #include 5 | 6 | class studentRecord 7 | { 8 | public: 9 | studentRecord(); 10 | studentRecord(int newGrade, int newID, std::string newName); 11 | int grade(); 12 | bool isValidGrade(int grade); 13 | void setGrade(int newGrade); 14 | int studentID(); 15 | void setStudentID(int newID); 16 | std::string name(); 17 | void setName(std::string newName); 18 | std::string letterGrade(); 19 | private: 20 | int _grade; 21 | int _studentID; 22 | std::string _name; 23 | }; 24 | 25 | #endif // STUDENTRECORD_H 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Think-Like-a-Programmer 2 | A place for me to save my code as I work through "Think Like A Programmer: An Introduction to Creative Problem Solving" 3 | --------------------------------------------------------------------------------