With the last post available for a while, it is time to go on more questions with C++. It is served as schoolwork for most learners.
Stage 1
The first stage is described in detail in the former post.
Stage 2
Question 2.1
Given three integer m, n and x and 0<x<m<n, code a program that outputs all the integers in [m,n], divide x into which, with remainder less than 5. Finally, output the sum of the squares of these integers.
Sample I/O
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Input: 11 Input: 25 Input: 8 Outputs: 11 12 16 17 18 19 20 24 25 Sum of Squares: 3096
/// /// @file 04-range-remainders.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 2, 2024 /// @version 0.2 /// @brief The use of math theorem, permutation and logic. ///
#include<iostream>
intmain(int argc, char* argv[]){ int m, n, x, counter = 0, sum = 0; // first step: get the value of m, n and x std::cout << "Input: m="; std::cin >> m; std::cout << "Input: n="; std::cin >> n; std::cout << "Input: x="; std::cin >> x; // next step: ensuring the inputs are correct, traverse the integers in [m, n] // then judge if each integer satisfies the requirements if (x > 0 && m > x && n > m) { std::cout << "Outputs:" << std::endl; for (int output = m; output <= n; output++) { int remainder = output % x; if (remainder < 5) { cout << output << endl; sum += output * output; counter++; } } if (counter == 0) { std::cout << "NONE" << std::endl; } std::cout << "Sum of Squares: " << sum << std::endl; } else { std::cout << "Input(s) invalid. Inputs must satisfy 0<x<m<n!" << std::endl; } return0; }
Question 2.2
Code to meet the following functions.
Within an infinite loop, allow the user to input one integer a time continuously. When a second 0 is inputed, stop the loop and output the sum between the two inputs of 0.
/// /// @file 05-sum-with-valid-range.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 2, 2024 /// @version 0.2 /// @brief The use of math theorem, permutation and logic. ///
#include<iostream>
intmain(int argc, char* argv[]){ // Step 1: define the variables with initial value specified for the judgement that the input is not 0 // Note that "invalid" and "valid" should be non-zero, or the loops are in vain. int invalid = 233, valid = 233, sum = 0; std::vector<int> result; // Step 2: allow inputting any invalid non-zero values until the first 0 is input while (invalid != 0) { std::cout << "Input: "; std::cin >> invalid; } // Step 3: sum all the valid values until a second 0 is input // Possible improvement: reduce space complexity to O(1). for (counter = 0; valid != 0; counter++) { std::cout << "Input: "; std::cin >> valid; result.insert(result.begin() + counter, valid); } for (int i = 0; i < counter; i++) { sum += result[i]; } // Finally, output the sum std::cout << "Output: " << sum << std::endl; return0; }
Stage 3
Question 3.1
Code to meet the following functions.
Given 16 double-digit integers (not repeating in the range of 10 ~ 99), put them into a 4×4 matrix so that they are arranged from large to small in the order shown in the figure below.
Then after inputting another double-digit integer, search the matrix for it and output the coordination if found; else output "Not Found".
Postscript
Just correctly output which row and which column. There is no need to define a 2-dimensional array.
/// /// @file 06-sort-and-search.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 3, 2024 /// @version 0.2 /// @brief The use of bubble sort and binary search. ///
#include<iostream>
intmain(int argc, constchar* argv[]){ // Step 1: considering no need of 2-d array, therefore a 1-d array is defined int a[16], low, high, mid, input; bool finished, right = true, down = true; std::cout << "Input: "; for (int i = 0; i < 16; i++) std::cin >> a[i]; // Step 2: using bubble sort algorithm, arrange each element of the array from large to small, time complexity: O(n*n) for (int i = 1; i < 16; i++) { // Note that the following "finished" is hypothesized as true. It will turn into false unless the following loop changes nothing of the array. finished = true; for (int j = 0; j < 16 - i; j++) { if (a[j] < a[j + 1]) { finished = false; int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } if (finished) break; } // Step 3: following the sequence by size of each element of the matrix above, first search for the input, and then output the answer std::cout << "Input: "; std::cin >> input; std::cout << "Output: "; low = 0; high = 15; while (low <= high) { mid = (low + high) / 2; if (input == a[mid]) break; if (input < a[mid]) low = mid + 1; else high = mid - 1; } if (low > high) std::cout << "Not Found" << std::endl; else { // Note that the size and the rule of sequence of the matrix is fixed, so there is no need to invent an algorithm to satisfy the feature. Only 16 cases are to be considered. switch (mid) { case0: std::cout << "0, 0" << std::endl; break; case1: std::cout << "0, 1" << std::endl; break; case2: std::cout << "0, 2" << std::endl; break; case3: std::cout << "0, 3" << std::endl; break; case4: std::cout << "1, 3" << std::endl; break; case5: std::cout << "2, 3" << std::endl; break; case6: std::cout << "3, 3" << std::endl; break; case7: std::cout << "3, 2" << std::endl; break; case8: std::cout << "3, 1" << std::endl; break; case9: std::cout << "3, 0" << std::endl; break; case10: std::cout << "2, 0" << std::endl; break; case11: std::cout << "1, 0" << std::endl; break; case12: std::cout << "1, 1" << std::endl; break; case13: std::cout << "1, 2" << std::endl; break; case14: std::cout << "2, 2" << std::endl; break; case15: std::cout << "2, 1" << std::endl; break; default: std::cout << "Internal Method Error. Sorry about this!" << std::endl; } } return0; }
Question 3.2
Code to meet the following functions.
There is an English sentence with letters and spaces only (no punctuations or other non-alphabetic symbols), in which every word is less than 10 letters, and the sentence is no more than 10 words. Connect all words with the same length to a longer “word”. Output the “words” after connection from short to long. If the “words” after connection share the same length, put the word with more connection operations in the front.
Sample I/O
1 2
Input: This is a good day for us to work Output: a isusto dayfor Thisgoodwork
1 2
Input: This is a bad day for us to work Output: a isusto Thiswork baddayfor
Solution
It is not easy for most first learners. It seems much harder than the first look.
/// /// @file 07-rearrange-words.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 3, 2024 /// @version 0.2 /// @brief The use of math theorem, permutation and logic. ///
#include<iostream>
intmain(int argc, constchar* argv[]){ usingnamespace std; char words[10][11], sentence[110], key = ' '; int counter = 0, length[10] = {0}, total_length[10] = {0}; // Step 1: get the line of the special sentence; 110 equals to 10(words) times 11(maximum size -- 10 -- of a word, with additional one character '\0') std::cout << "Input: "; std::cin.getline(sentence, 110); std::cout << "Output: "; // Step 2: count the total words and save the count for (int i = 0; sentence[i] != '\0'; i++) { if (key == ' ' && sentence[i] != ' ') counter++; key = sentence[i]; } // Step 3: calculate the lengths of the words and store them into an array key = ' '; for (int i = -1, j = 0; i < counter && key != '\0'; j++) { if (key == ' ' && sentence[j] != ' ') i++; while (sentence[j] != '\0') if (sentence[j] != ' ') { length[i]++; j++; } else break; key = sentence[j]; } // Step 4: split each word into different rows in a two-dimensional array for (int i = 0, k = 0; i < counter; i++) { for (int j = 0; j < length[i]; j++, k++) words[i][j] = sentence[k]; while (sentence[k] == ' ') k++; } // Step 5: calculate the total length of words sharing the same (1~10) lengths for (int i = 1; i <= 10; i++) for (int j = 0; j < counter; j++) if (length[j] == i) total_length[i - 1] += i; // Step 6: by traverse, output "words" from short to long // Considering the total length is no more than 100, therefore just try every possible total length. for (int sum = 1; sum <= 100; sum++) for (int i = 0; i < 10; i++) if (total_length[i] == sum) { for (int j = 0; j < counter; j++) if (length[j] == i + 1) for (int k = 0; k < length[j]; k++) std::cout << words[j][k]; std::cout << ' '; } std::cout << std::flush; return0; }
Stage 4
Question 4.1
Define an array int arr[7] in function main() that stores 7 natural numbers smaller than 15 (repetition exists). To process arr, you will design a function called myfun(), which returns the sum of the numbers where there are odd non-zero integers in arr, or returns the product of the non-zero integers when they are even. Finally, output the returned value in main(). However, there are restrictions below:
myfun() has only one parameter, which transmits the argument arr.
In myfun(), only one loop, which is specifically an ordinary counter loop, is allowed.
There are no conditional, relational, or logical expressions in the whole program except for this loop control line. Note that if, switch, loop control lines, question mark colon expressions, etc. are conditional expressions.
/// /// @file 08-no-loops-condition-logic.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 4, 2024 /// @version 0.2 /// @brief The use of function, enumeration and boolean algebra. /// @note The use of condition expressions, logic expressions, /// relation expressions and loops are not allowed in this file. ///
#include<iostream>
intmyfun(int *arr){ // Step 1: use as many local variables as possible for easier calculation int result, sum = 0, product = 1; bool result_is_product = true; bool not_zero = true; // if current element is not zero not_zero = arr[0]; // the result to return is flipped, else do not change the value result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); // add the element to the sum and multiply the product sum += arr[0]; product *= ((int)not_zero * arr[0] + (int)(true - not_zero)); // do the things above 7 times (7 is the size of input elements in function // "main") If the question does not imply the size, this function must // involve an infinite loop to finish calculation. not_zero = arr[1]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[1]; product *= ((int)not_zero * arr[1] + (int)(true - not_zero)); // 2 not_zero = arr[2]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[2]; product *= ((int)not_zero * arr[2] + (int)(true - not_zero)); // 3 not_zero = arr[3]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[3]; product *= ((int)not_zero * arr[3] + (int)(true - not_zero)); // 4 not_zero = arr[4]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[4]; product *= ((int)not_zero * arr[4] + (int)(true - not_zero)); // 5 not_zero = arr[5]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[5]; product *= ((int)not_zero * arr[5] + (int)(true - not_zero)); // 6 not_zero = arr[6]; result_is_product = (not_zero * (true - result_is_product)) + ((true - not_zero) * (result_is_product)); sum += arr[6]; product *= ((int)not_zero * arr[6] + (int)(true - not_zero)); // What to return? Let's determine it. result = ((int)result_is_product * product + (int)(true - result_is_product) * sum); return result; }
/// /// @file 09-function-fixed-return.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 4, 2024 /// @version 0.2 /// @brief The use of static function variable. /// @note Do not overload functions. No global variables. /// No more than three semicolons(;) and no commas(,) in function "SpaceCounter". /// Do not include libraries other than "iostream". /// The function "main" must completely executed without early exit. ///
The program lets the user enter two strings of letters, saves them in two character arrays, and then swaps the non-empty characters with the same subscript, and finally output the two new strings. Both strings of letters entered by the user are less than 20 (in upper and lower case) with an enter as the input of a string finishes, and do not contain any other characters. Additionally, there are restrictions:
No libraries other than iostream are included.
Only two character arrays with length of 20, one character variable and one character pointer are allowed to define and use.
To the character variable above, only assignment operation is allowed. That is, no arithmetic or other operations (including compound assignment, self increase and self decrease, etc.).
/// /// @file 10-swap-two-strings.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 6, 2024 /// @version 0.2 /// @brief The use of swap method, pointers and addresses. /// @note Do not include libraries other than "iostream". /// ONLY ONE char, ONE char pointer, TWO char arrays are /// allowed to be defined. The only char should ONLY be /// assigned. DO NOT use it for calculation. ///
#include<iostream>
intmain(int argc, char* argv[]){ // Step 1: define the variables with initial values of NULL char letter = 0, *counter = nullptr, a[20] = {0}, b[20] = {0}; // Step 2: input two strings of characters with an enter as finishing input std::cout << "Input: "; std::cin.getline(a, 20); std::cout << "Input: "; std::cin.getline(b, 20); // Step 3: with the help of pointer counter, swap valid characters until a NULL is detected for (counter = &a[0]; a[counter - &a[0]] != '\0' && b[counter - &a[0]] != '\0'; counter++) { letter = a[counter - &a[0]]; a[counter - &a[0]] = b[counter - &a[0]]; b[counter - &a[0]] = letter; } // Step 4: output the result after swapping std::cout << "Output: " << a << std::endl; std::cout << "Output: " << b << std::endl; return0; }
Question 5.2
Fill in the blank in main() and func() below so that the whole program can determine whether a positive integer input by the user is a palindrome number (i.e. a number reads the same backward as forward). Note that you can only add your code on the position of // BLANK FILLINGs, and user will just input a number and an enter when the input is completed. By the way, there are restrictions:
No new variables, arrays or any other objects.
No loops.
No library functions called in the definition of func().
The total of semicolons and commas of your fillings is no more than 10.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include<iostream> #include<cstring>
usingnamespace std;
boolfunc(char array[], int len);
intmain(){ char ch[20]; bool result;
cout<< "Input: "; cin >> ch; // Write your own code below. return0; } boolfunc(char array[], int len){ // Write your own code below. }
/// /// @file 11-palindromic-number.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 6, 2024 /// @version 0.2 /// @brief The use of recursive function calls. /// @note No more than 10 semicolons(;) and commas(,) total /// in your self-written code. /// You can ONLY write your own code in the areas given /// (See comments in the functions). /// DO NOT call library functions in function "func". /// DO NOT use loops. NO MORE self-defined objects. ///
#include<iostream> #include<cstring>
usingnamespace std;
boolfunc(char array[], int len);
intmain(){ char ch[20]; bool result;
cout<< "Input: "; cin >> ch;
// Write your own code below. // Note that "result" given by the question is useless. Just let the return value of "func()" be the judgement expression. if (func(ch, strlen(ch))) cout << "Output: Yes" << endl; else cout << "Output: No" << endl; // 2 semicolons(;) & 1 comma(,) return0; }
boolfunc(char array[], int len){ // Write your own code below. if (len == 1 || len == 0) returntrue; if (array[0] == array[len - 1]) if(func(array + 1, len - 2)) returntrue; returnfalse; // 3 semicolons(;) & 1 comma(,) } // TOTAL 5 SEMICOLONS AND 2 COMMAS
Stage 6
Question 6.1
Code to meet the following needs.
The user will enter a line of sentence with at most 10 words, 100 characters. Count and output how many words the sentence has. Then the user will input a string of numbers to express the new sequence of the words. Output the sentence with the new sequence of the words. Additionally, all the arrays you are going to use should be defined by new. Note that the sentence user inputs contains letters and spaces only and no spaces at the end of the sentence, but an enter; and the string of numbers is guaranteed to express a right sequence of words in the sentence, i. e. no exceptional case.
Sample I/O
1 2 3 4
Input: Welcome to my hometown Output: 4 Input: 1302 Output: to hometown Welcome my
1 2 3 4
Input: This is a good day to work Output: 7 Input: 6543210 Output: work to day good a is This
/// /// @file 12-new-rearrange-words.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 6, 2024 /// @version 0.2 /// @brief The use of standard library and ADT strings. /// @note The user just input no more than 100 characters /// and each word has no more than 10 characters. ///
#include<iostream>
intmain(int argc, constchar* argv[]){ // Step 1: input a sentence without a full stop(.) std::string input; std::cout << "Input: "; std::getline(std::cin, input); // The last element of a char string is nullptr. char* sentence = newchar[input.length() + 1]; // Copy string to the char array "sentence". input.copy(sentence, input.length() + 1, 0); // Step 2: count the words input and output char key = ' '; int counter = 0; for (int i = 0; sentence[i] != '\0'; i++) { if (key == ' ' && sentence[i] != ' ') counter++; key = sentence[i]; } std::cout << "Output: " << counter << std::endl; // Step 3: calculate the length of each word and store in the array int* length = newint[counter]; for (int i = -1, j = 0; i < counter && key != '\0'; j++) { if (key == ' ' && sentence[j] != ' ') i++; while (sentence[j] != '\0') if (sentence[j] != ' ') { length[i]++; j++; } else break; key = sentence[j]; } // Step 4: split each word and store in the 2-d array char** words = newchar* [counter]; for (int i = 0; i < counter; i++) words[i] = newchar[length[i]]; for (int i = 0, k = 0; i < counter; i++) { for (int j = 0; j < length[i]; j++, k++) words[i][j] = sentence[k]; while (sentence[k] == ' ') k++; } // Release the heap memory of "sentence". delete [] sentence; // Step 5: input the new order of the words char* order = newchar[counter]; std::cout << "Input: "; for (int i = 0; i < counter; i++) std::cin >> order[i]; // Convert char array to int array. int* result = newint[counter]; for (int i = 0; i < counter; i++) result[i] = order[i] - '0'; std::cout << "Output: "; for (int i = 0; i < counter; i++) { for (int j = 0; j < length[result[i]]; j++) std::cout << words[result[i]][j]; std::cout << ' '; } // Release the heap memory of "length", "words", "order", "result". for (int i = 0; i < counter; i++) delete [] words[i]; delete [] length, words, order, result; return0; }
Question 6.2
Fill in the blank with restrictions below so that the program will output three numbers, the first of which is the ones place of x minus y, the second of which is triple x, and the third of which is double y, where x is the first number input and y the second. The restrictions are described in the annotations of the code. Note that there needs a space between the output numbers, as the sample shows, and do not add or modify anything except where the annotations are.
// Fill two lines of code below. // Fill two lines of code above. intmyfun(int *a, int *b);
intmain(void){ int x, y; cout << "Input: "; cin >> x >> y; cout << "Output: "; cout << myfun(x, y); cout << x << ' ' << y; return0; } intmyfun(int *a, int *b){ int c = *a - *b; *a *= 2; *b *= 3; return c; } // Define only one function here. The function body has only 2 lines (at most 2 semicolons) of code and no names of arrays.
/// /// @file 13-pointers-and-overload.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 6, 2024 /// @version 0.2 /// @brief The use of standard library and reference. /// @note The user just input no more than 100 characters /// and each word has no more than 10 characters. ///
#include<iostream> usingnamespace std;
// Fill two lines of code below. #define ABS_INT(integer) ((integer >= 0)? integer : -integer) string myfun(int &a, int &b); // Fill two lines of code above. intmyfun(int *a, int *b);
intmyfun(int *a, int *b){ int c = *a - *b; *a *= 2; *b *= 3; return c; }
// Define a function below. /// @note This function must contain NO MORE THAN 2 semicolons(;) /// and NO commas(,) unless it is for function parameters. string myfun(int &a, int &b){ int first = myfun(&b, &a); returnto_string(ABS_INT(first) % 10) + string(" "); }
Stage 7
Question 7.1
Write out the declaration and definitions of two functions funA() and funB() below so that funA() has the access to an inputted string from pointer p and funB() turns all the numbers of the string into '0' and outputs the string. You need to make sure that no memory leak happens at the end of each program block, and the program has correct newlines as the sample below shows. Note that the input by the user is a string of letters and numbers, less than 8 characters, and an enter as the input finishes.
/// /// @file 13-pointers-and-overload /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 8, 2024 /// @version 0.2 /// @brief The use of function, reference and pointers. /// @note Please ensure no memory leaks during runtime. ///
// Define two functions below. /// @brief This function is to create a char pointer so /// that the reference type matches the RHS. /// @note This function is used as left value, /// so the return type must be reference. char* &funA(char** &p){ p = newchar*; return *p; }
/// @note The string must have no more than 8 chars. char* funB(char* invalid, char* &p){ short length = strlen(p); if (length > 8) { cout << "PANIC: illegal input" << endl; exit(-1); } for (short i = 0; i < length; i++) if (p[i] - '0' > 0 && p[i] - '0' <= 9) p[i] = '0'; p[length] = '\n'; p[length + 1]= '\0'; return p; }
Actor &GetPlayer(char[], int); Actor &GetEnemy(int); voidAction(Actor&, Actor&, int);
intmain(){ char name[10]; int money, act; cout << "What's your name? (No more than 9 letters) "; cin >> name; cout << "How much will you pay for the game? $"; cin >> money; Actor &player = GetPlayer(name, money); Actor &enemy = GetEnemy(money); cout << "===== " << player.name << " vs " << enemy.name << " =====" << endl; if (money < 1) { cout << "You Lose!" << endl; return0; } for (int i = 1; i <= 10; ++i) { cout << "Round " << i << endl; // Write some code below. Action(player, enemy, act); if (enemy.hp < 10 && enemy.heal) act = 2; else act = 1; Action(enemy, player, act); if (player.hp > 0 && enemy.hp <= 0) { cout << "You Win!" << endl; return0; } elseif (enemy.hp > 0 && player.hp <= 0) { cout << "You Lose!" << endl; return0; } elseif (player.hp <= 0 && enemy.hp <= 0) { cout << "End of Game with Draw." << endl; return0; } cout << player.name << "'s remaining HP: " << player.hp << endl; cout << enemy.name << "'s remaining HP: " << enemy.hp << endl; cout << "------------------------------------------" << endl; } cout << "End of Game with Draw." << endl; return0; }
Actor &GetPlayer(char name[], int m){ Actor *player = newActor({name, m, m / 2, m / 3, m >= HEAL_VALID}); // Write some code below. }
Actor &GetEnemy(int m){ Actor *enemy; int choice; cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): "; cin >> choice; if (choice) enemy = newActor({(char*)"Slime", 20 + m / 5, 8 + m / 6, 7 + m / 6, true}); else enemy = newActor({(char*)"Wolf", 25 + m / 4, 9 + m / 6, 6 + m / 6, false}); // Write some code below. }
voidAction(Actor &user, Actor &target, int act){ if (act == 1) { cout << user.name << " attacks " << target.name << "!" << endl; int damage = user.atk - target.def; if (damage < 0) damage = 0; target.hp -= damage; } elseif (act == 2) { cout << user.name << " does self-healing!" << endl; user.hp += HEAL_EFFECT; } else cout << user.name << " is waiting..." << endl; }
Code to complete a simple and crude game starting with topping up. The features of the game:
The player chooses the action of every round, 1 for attack, 2 for heal, 3 for wait.
The heal is available when the player tops up at least $20, that is, heal is hidden when a lower money is topped up.
The whole game plays like the samples shown below.
Note that you can only add your code to complete the game code where the annotations are, and do not worry about wrong inputs from the player. By the way, when you finish this game, you can consider expanding more features like new actions (e.g. tool, escape), new enemies, or more attack force when the enemy has a low HP, etc.
What's your name? (No more than 9 letters) Jack How much will you pay for the game? $30 Welcome to this game, Jack! Your status: HP30, ATK15, DEF10 You can attack the enemy and heal yourself. Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): 0 Your enemy Wolf: HP32, ATK14, DEF11 ===== Jack vs Wolf ===== Round 1 Jack's act (1-attack; 2-heal; otherwise-wait): 1 Jack attacks Wolf! Wolf attacks Jack! Jack's remaining HP: 26 Wolf's remaining HP: 28 --------------------- Round 2 Jack's act (1-attack; 2-heal; otherwise-wait): 1 Jack attacks Wolf! Wolf attacks Jack! Jack's remaining HP: 22 Wolf's remaining HP: 24 --------------------- (the player enters "1" over Round 3-6, shorten here) --------------------- Round 7 Jack's act (1-attack; 2-heal; otherwise-wait): 1 Jack attacks Wolf! Wolf attacks Jack! Jack's remaining HP: 2 Wolf's remaining HP: 4 --------------------- Round 8 Jack's act (1-attack; 2-heal; otherwise-wait): 2 Jack does self-healing! Wolf attacks Jack! Jack's remaining HP: 8 Wolf's remaining HP: 4 --------------------- Round 9 Jack's act (1-attack; 2-heal; otherwise-wait): 1 Jack attacks Wolf! Wolf attacks Jack! You Win!
What's your name? (No more than 9 letters) Tom How much will you pay for the game? $15 Welcome to this game, Tom! Your status: HP15, ATK7, DEF5 You can attack the enemy but not heal yourself. Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): 0 Your enemy Wolf: HP28, ATK11, DEF8 ===== Tom vs Wolf ===== Round 1 Tom's act (1-attack; otherwise-wait): 1 Tom attacks Wolf! Wolf attacks Tom! Tom's remaining HP: 9 Wolf's remaining HP: 28 --------------------- Round 2 Tom's act (1-attack; otherwise-wait): 2 Tom is waiting... Wolf attacks Tom! Tom's remaining HP: 3 Wolf's remaining HP: 28 --------------------- Round 3 Tom's act (1-attack; otherwise-wait): 1 Tom attacks Wolf! Wolf attacks Tom! You Lose!
/// /// @file 15-games-class-members.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 8, 2024 /// @version 0.2 /// @brief The use of class. ///
Actor &GetPlayer(char[], int); Actor &GetEnemy(int); voidAction(Actor&, Actor&, int);
intmain(){ char name[10]; int money, act; cout << "What's your name? (No more than 9 letters) "; cin >> name; cout << "How much will you pay for the game? $"; cin >> money; Actor &player = GetPlayer(name, money); Actor &enemy = GetEnemy(money); cout << "===== " << player.name << " vs " << enemy.name << " =====" << endl; if (money < 1) { cout << "You Lose!" << endl; return0; } for (int i = 1; i <= 10; ++i) { cout << "Round " << i << endl; // Write some code below. cout << player.name << (player.heal ? "'s act (1-attack; 2-heal; otherwise-wait): " : "'s act (1-attack; otherwise-wait): "); cin >> act; if (!player.heal && act == 2) act++; Action(player, enemy, act); if (enemy.hp < 10 && enemy.heal) act = 2; else act = 1; Action(enemy, player, act); if (player.hp > 0 && enemy.hp <= 0) { cout << "You Win!" << endl; return0; } elseif (enemy.hp > 0 && player.hp <= 0) { cout << "You Looose!" << endl; return0; } elseif (player.hp <= 0 && enemy.hp <= 0) { cout << "End of Game with Draw." << endl; return0; } cout << player.name << "'s remaining HP: " << player.hp << endl; cout << enemy.name << "'s remaining HP: " << enemy.hp << endl; cout << "------------------------------------------" << endl; } cout << "End of Game with Draw." << endl; // draw: v. & n. 平局 return0; }
Actor &GetPlayer(char name[], int m){ Actor *player = newActor({name, m, m / 2, m / 3, m >= HEAL_VALID}); // Write some code below. cout << "Welcome to this game, " << player -> name << "!\n"; cout << "Your status: HP" << player -> hp << ", ATK" << player -> atk << ", DEF" << player -> def << '\n'; cout << (player -> heal ? "You can attack the enemy and heal yourself." : "You can attack the enemy but not heal yourself.") << endl; return *player; }
Actor &GetEnemy(int m){ Actor *enemy; int choice; cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): "; cin >> choice; if (choice) enemy = newActor({(char*)"Slime", 20 + m / 5, 8 + m / 6, 7 + m / 6, true}); else enemy = newActor({(char*)"Wolf", 25 + m / 4, 9 + m / 6, 6 + m / 6, false}); // Write some code below. cout << "Your enemy " << enemy -> name << ": HP" << enemy -> hp << ", ATK" << enemy -> atk << ", DEF" << enemy -> def << endl; return *enemy; }
voidAction(Actor &user, Actor &target, int act){ if (act == 1) { cout << user.name << " attacks " << target.name << "!" << endl; int damage = user.atk - target.def; if (damage < 0) damage = 0; target.hp -= damage; } elseif (act == 2) { cout << user.name << " does self-healing!" << endl; user.hp += HEAL_EFFECT; } else cout << user.name << " is waiting..." << endl; }
Stage 8
Question 8.1
As the code shown below, write your declaration and definition of function myfun() and fill in the blanks of main(), so that the program conducts the matrix multiplication of A and B, where A is a 3×n matrix and B is an n×3 matrix. Additionally, one of A and B need to be stored by a pointer to array and the other by an array of pointers, and all the elements of B are continuous in the memory. Note that the output format should be identical as the sample shows.
/// /// @file 16-matrix-multiplication.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 8, 2024 /// @version 0.2 /// @brief The use of pointers and matrix multiplication. ///
#include<iostream> usingnamespace std;
// Declare function "myfun" below. voidmyfun(int*, int*, int);
intmain(){ int n; cout << "Input n: "; cin >> n; cout << "Input A: "; // Write some code below. // A is an array of (int) pointers. int* A[3]; for (int i = 0; i < 3; i++) A[i] = newint[n]; for (int i = 0; i < 3; i++) for (int j = 0; j < n; j++) cin >> A[i][j]; cout << "Input B: "; // Write some code below. // B is a pointer to a dynamic 1-d array. int* B = newint[n * 3]; for (int i = 0; i < n * 3; i++) cin >> B[i]; cout << "Output:\n"; for(int i = 0; i < 3; ++i) myfun(A[i], B, n); delete [] B; return0; } // Define function "myfun" below. voidmyfun(int* a, int* b, int n){ for (int i = 0; i < 3; i++) { int sum = 0; for (int j = 0; j < n; j++) sum += a[j] * b[i + j * 3]; cout << sum << ' '; } cout << endl; }
Question 8.2
Add one word to each of the two source files below so that the project made up of the two can be compiled to a runnable program.
intmyfun(int n){ externint x; // Add "extern" to import global x = 10 from another cpp file. Only establish the aim in this way. returnyourfun(n + x); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/// /// @file 17-another-source-library.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 8, 2024 /// @version 0.2 /// @brief The use of static functions. ///
int x = 10;
/// @note Add "static" so that the function is only available to this file. staticintmyfun(int n){ return n * 2; }
intyourfun(int y){ returnmyfun(y); }
Stage 9
The Requirements
Please fill in all the blanks in the code below. The I/O samples are like those in Stage 7. The main difference from Stage 7 is the total budget, which turns to $50, and the player can buy a sword for $10. Note that you should not modify any code other than where the blanks are, and don’t worry about wrong inputs from the player. By the way, after finishing this stage, you can consider adding some new enemies, new weapons or something else you like to the game.
intmain(){ char name[10]; int money, enemy_choice, weapon_choice; Weapon sword(10, 10); cout << "What's your name? (No more than 9 letters) "; cin >> name; cout << "You have $" << TOTAL_MONEY << " in total." << endl; cout << "How much will you pay for your basic attributes? $"; cin >> money; Actor player(name, money); cout << "---------------------" << endl; cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): "; cin >> enemy_choice; Actor enemy(enemy_choice, money); cout << "---------------------" << endl; cout << "You have $" << TOTAL_MONEY - money << " left." << endl; if (TOTAL_MONEY - money >= sword.price) { cout << "If you want to spend $10 to buy a sword, input 1: "; cin >> weapon_choice; if (weapon_choice == 1) { cout << name << " has a sword now! ATK+" << sword.effect << "!" << endl; player.equip(sword); } else cout << name << " has no sword." << endl; } cout << "===== " << player.get_name() << " vs " << enemy.get_name() << " =====" << endl; if (money < 1) { cout << "You Looose!" << endl; return0; } for (int i = 1; i <= 10; ++i) { cout << "Round " << i << endl; player.Action(enemy); enemy.Action(player); cout << player.get_name() << "'s remaining HP: " << player.get_hp() << endl; cout << enemy.get_name() << "'s remaining HP: " << enemy.get_hp() << endl; cout << "---------------------" << endl; // BLANK FILLING #3 // The code needed here is to determine whether the fight is over and the victory or defeat information is the same as that in Stage 7. } cout << "End of Game with Draw." << endl; return0; }
// BLANK FILLING #4 /* A HEAD OF A FUNCTION()*/ { // BLANK FILLING #5 // The code needed here is to set the basic attributes of the player, show welcome and status message like those in Stage 7 cout << "You can act with 1 to attack the enemy, " << (heal ? "2 to heal yourself, " : "") << "and otherwise wait." << endl; }
// BLANK FILLING #6 // The code needed here is the definition of a function that the options of enemy, the attributives of the enemy and the output of the information of the enemy are the same as those in Stage 7.
// BLANK FILLING #7 // The code needed here is the definition of a function that the options for the player, the actions of the enemy, the changes of HP of both sides and the output messages are the same as those in Stage 7.
/// /// @file 18-game-class-constructor.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 9, 2024 /// @version 0.2 /// @brief The use of class. /// @note Do not modify or write more code unless allowed in /// the limited places (see comments). ///
classWeapon { // Write some code below. public: Weapon(int a, int b): effect(a), price(b) {} // Write some code above. constint effect; constint price; };
classActor { char *name; int hp; int atk; int def; bool heal; bool isPlayer; // Write some code below. public: Actor(char[], int); Actor(int, int); voidAction(Actor &); // Write some code above. voidequip(Weapon &w){ atk += w.effect; }; char *get_name(){ return name; }; intget_hp(){ return hp; }; };
intmain(){ char name[10]; int money, enemy_choice, weapon_choice; Weapon sword(10, 10); cout << "What's your name? (No more than 9 letters) "; cin >> name; cout << "You have $" << TOTAL_MONEY << " in total." << endl; cout << "How much will you pay for your basic attributes? $"; cin >> money; Actor player(name, money); cout << "---------------------" << endl; cout << "Input a digit to choose your enemy (0 for Wolf, or otherwise Slime): "; cin >> enemy_choice; Actor enemy(enemy_choice, money); cout << "---------------------" << endl; cout << "You have $" << TOTAL_MONEY - money << " left." << endl; if (TOTAL_MONEY - money >= sword.price) { cout << "If you want to spend $10 to buy a sword, input 1: "; cin >> weapon_choice; if (weapon_choice == 1) { cout << name << " has a sword now! ATK+" << sword.effect << "!" << endl; player.equip(sword); } else cout << name << " has no sword." << endl; } cout << "===== " << player.get_name() << " vs " << enemy.get_name() << " =====" << endl; if (money < 1) { cout << "You Looose!" << endl; return0; } for (int i = 1; i <= 10; ++i) { cout << "Round " << i << endl; player.Action(enemy); enemy.Action(player); cout << player.get_name() << "'s remaining HP: " << player.get_hp() << endl; cout << enemy.get_name() << "'s remaining HP: " << enemy.get_hp() << endl; cout << "---------------------" << endl; // Write some code below so that the output is the same as in the file "15-game-class-members.cc" if (player.get_hp() > 0 && enemy.get_hp() <= 0) { cout << "You Win!" << endl; return0; } elseif (enemy.get_hp() > 0 && player.get_hp() <= 0) { cout << "You Looose!" << endl; return0; } elseif (player.get_hp() <= 0 && enemy.get_hp() <= 0) { cout << "End of Game with Draw." << endl; return0; } } cout << "End of Game with Draw." << endl; return0; }
// Write some code below so that the input/output is the same as in the file "15-game-class-members.cc" Actor::Actor(char a[], int b): name(a), hp(b), atk(b / 2), def(b / 3), heal(b >= HEAL_VALID), isPlayer(true) { cout << "Welcome to this game, " << name << "!\n"; cout << "Your status: HP" << hp << ", ATK" << atk << ", DEF" << def << '\n'; cout << "You can attack the enemy " << (heal ? "and" : "but not") << " heal yourself." << endl; cout << "You can act with 1 to attack the enemy, " << (heal ? "2 to heal yourself, " : "") << "and otherwise wait." << endl; } // Define a function below so that the attributes behave the same as in the file "15-game-class-members.cc" Actor::Actor(int a, int b): heal(a), isPlayer(false) { if (heal) { name = (char*)"Slime"; hp = 20 + b / 5; atk = 8 + b / 6; def = 7 + b / 6; } else { name = (char*)"Wolf"; hp = 25 + b / 4; atk = 9 + b / 6; def = 6 + b / 6; } cout << "Your enemy " << name << ": HP" << hp << ", ATK" << atk << ", DEF" << def << endl; } // Define a function below so that the attributes behave the same as in the file "15-game-class-members.cc" voidActor::Action(Actor &entity){ int act; if (!entity.isPlayer) { cout << this -> name << "'s act (1-attack; " << (this -> heal ? "2-heal; " : "") << "otherwise-wait): " << flush; cin >> act; if (!(this -> heal) && act == 2) act++; } else { if (this -> hp < 10 && this -> heal) act = 2; else act = 1; } if (act == 1) { cout << this -> name << " attacks " << entity.name << "!" << endl; int damage = this -> atk - entity.def; if (damage < 0) damage = 0; entity.hp -= damage; } elseif (act == 2) { cout << this -> name << " does self-healing!" << endl; this -> hp += HEAL_EFFECT; } else cout << this -> name << " is waiting..." << endl; }
Stage 10
The Requirements
Please fill in all the blanks in the code below.
The program simulates a cell culture environment where resource is initially 500.
Class Cell contains 2 private data members and 8 public member functions, no public data members or private member functions. The 2 private data members are size and resource, both of which are integers. The names of the 8 member functions are Cell(), ~Cell(), grow(), eat(), get_size(), get_resource(). You may notice that there are 8 functions but 6 names. init_size input from the user is in [1,100].
In each cycle of while, the following operations are performed: the initial cell and each ordinary cell that has been born will grow once; the growth of an ordinary cell will make its size increase by 1, while the resource in the whole environment decrease by 1; the growth of the initial cell will not change its size, but will still make the resource decrease by 1; if the size of an ordinary cell is greater than 5, then it will create a new ordinary cell, which is half the size of the original cell (rounding off the decimal), and the resource in the environment will be reduced by the size of the new cell.
Before the end of each cycle of while, if the size of the largest cell in the environment is greater than 10, the initial cell will eat it and increase the resource in the environment by an amount equal to the size of the eaten cell.
When the resource in the environment is reduced to 0 or negative, or when the 100th ordinary cell is created, the while cycle should be interrupted.
cells[0] = newCell(*init_cell); cout << "Cell 0 is born, remaining resource = " << Cell::get_resource() << endl; while (true) { // BLANK FILLING #2 // Step 3: guess the code to be written from the output demonstration // First, grow the "init_cell". init_cell -> grow(); // Then, let other cells grow if the conditions meet. for (int i = 0, stop = id; i < stop && Cell::get_resource() > 0 && id <= 100; i++) if (cells[i]) { cells[i] -> grow(i); // Spawn more normal cells if the resources are enough. if (cells[i] -> get_size() > 5 && Cell::get_resource() >= cells[i] -> get_size() / 2) { cells[id] = newCell(cells[i] -> get_size() / 2); cout << "Cell " << id++ << " is born, remaining resource = " << Cell::get_resource() << endl; } } // Choose one with the biggest size from normal cells. for (i = 0, size = 0; i < id; i++) if (cells[i]) if (cells[i] -> get_size() > size) { size = cells[i] -> get_size(); eat = i; } // init_cell would eat cells if the conditions meet. if (size > 10 && Cell::get_resource() > 0) init_cell -> eat(eat, cells[eat]); // Finally, recycle all memory space and break the loop if the conditions meet. if (Cell::get_resource() <= 0 || id > 100) { delete init_cell; for (int i = 0; i < id && cells[i]; i++) delete cells[i]; break; } }
return0; }
// BLANK FILLING #3 // The code needed here is the implementation of class "Cell" // Step 4: initialize static class objects int Cell::resource = 500;
// Step 5: define all the functions of the class
/// @brief Get the private member "resource" of the class. intCell::get_resource(){ return resource; }
/// @brief Get the private member "resource" of the class (normal cells only). intCell::get_size(){ return size; }
/// @brief Constructor of new normal cells. Cell::Cell(int spawnSize) { if (spawnSize < 1 || spawnSize > 100) { cout << "Cell initialization failed." << endl; return; } size = spawnSize; resource -= spawnSize; }
/// @brief Let normal cells grow. voidCell::grow(int id){ size++; resource--; cout << "Cell " << id << " grows, remaining resource = " << resource << endl; }
/// @brief Let the initial cell eat. voidCell::eat(int id, Cell*& CellToEat)const{ delete CellToEat; CellToEat = nullptr; cout << "Cell " << id << " is eaten, remaining resource = " << resource << endl; }
/// @brief Let resources more if a cell dies. Cell::~Cell() { resource += size; }
Stage 11
The Requirements
Please fill in all the blanks in the code below so that the program runs the same as in Stage 10.
No global variables or functions are defined except for defining the derived class of Cell and implementing these two classes and their operator overloaded functions. The derived class of Cell contains two new private data members and no public data members. The two private data members are id and counter, both integers. The definition of the derived class of Cell only contains at most three member functions.
Note that operators that need to be overloaded have and only have =, << and >>.
/// /// @file 20-operator-overloads.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 11, 2024 /// @version 0.2 /// @brief The use of class operators. /// @note Do not moidify or write more code unless allowed in /// the limited places (see comments). ///
// BLANK FILLING #1 (Define a new class to derive class "Cell") // Do not define other global variables or functions unless they are operator overloads of the classes. // The class to derive "Cell" has 2 new private data members and no public data members. // The 2 private members must be called "id" and "counter", both are int. // The class to derive "Cell" has at most 3 member functions. // The operators needed to be overloaded are only = << and >> classNewCell: public Cell { friend ostream& operator<<(ostream& output, NewCell& target); // Step 1: declare the private integers private: int id; staticint counter; // Step 2: declare "operator=" overloads and "grow" method public: booloperator=(Cell& source); booloperator=(NewCell& source); boolgrow(void); }; // Write some code above.
intmain(){ Cell init_cell; NewCell cells[100]; int born = 1, eaten = 0, maxsize;
while (true) { if (init_cell.grow()) return0; int thisround = born; for (int i = 0; i < thisround; ++i) { if (cells[i].get_size() == 0) continue; if (cells[i].grow()) return0; if (cells[i].get_size() > 5) { if (cells[born] = cells[i]) return0; if (cells[born].get_size() > cells[eaten].get_size()) eaten = born; born++; if (born >= 100) return0; } } if (cells[eaten].get_size() > 10) { cout << cells[eaten]; eaten = 0, maxsize = 0; for (int i = 0; i < born; ++i) if (cells[i].get_size() > maxsize) { maxsize = cells[i].get_size(); eaten = i; } } } return0; }
// // BLANK FILLING #2 (Define everything in class "Cell" and its derived class) // Step 3: initialize the static members int Cell::resource = 500; int NewCell::counter = 0;
// Step 4: define all methods in classes
/// @brief Constructor of the initial cell (Cell #0). istream &operator>>(istream& input, Cell& initialCell) { int spawnSize; input >> spawnSize; // User must input an integer within range [1, 100]. if (spawnSize < 1 || spawnSize > 100) { cerr << "*** Invalid input! The input is now changed to 1. ***" << endl; spawnSize = 1; } initialCell.size = spawnSize; Cell::resource -= spawnSize; cout << "Initial Cell is born, remaining resource = " << Cell::resource << endl; return input; }
/// @brief Constructor of new normal cells. bool NewCell::operator=(Cell& initialCell) { if (this == &initialCell) returntrue; this -> id = counter++; this -> size = initialCell.get_size() / 2; resource -= initialCell.get_size() / 2; cout << "Cell " << id << " is born, remaining resource = " << Cell::resource << endl; returnfalse; }
/// @brief Spawn more normal cells if the resources are enough. bool NewCell::operator=(NewCell& source) { if (this == &source) returntrue; if (resource < source.size / 2) returnfalse; this -> id = counter++; this -> size = source.size / 2; resource -= source.size / 2; cout << "Cell " << id << " is born, remaining resource = " << Cell::resource << endl; returnfalse; }
/// @brief Let the initial cell grow. boolCell::grow(void){ if (resource <= 0) returntrue; resource--; cout << "Initial Cell grows, remaining resource = " << resource << endl; returnfalse; }
/// @brief Let normal cells grow. boolNewCell::grow(void){ if (resource <= 0) returntrue; this -> size++; resource--; cout << "Cell " << id << " grows, remaining resource = " << resource << endl; returnfalse; } // Write some code above.
Stage 12
The Requirements
Please fill all the blanks in the code below so that the program reads data of some characters from two files called actors_int.txt and actors_float.txt, and store into an array of Actor<int> and Actor<float> each. The total of characters of the two groups may not be equal but all characters from the two groups are no more than 20, to team up.
Then, according to threshold entered by the user, the program selects and outputs the qualified characters from the team to file team.txt. The qualified characters are required to meet at least three of the following four conditions: 1) HP is greater than threshold; 2) ATK is higher than threshold / 3; 3) DEF is higher than threshold / 3; 4) able to heal.
The output IDs are re-numbered from 1 in the order of int first and float then, and the internal characters of int (or float) are sorted from small to large according to the original IDs.
#include<iostream> #include<fstream> #define NUM 20 usingnamespace std;
classTeam; template <classT> classActor; // Declare a function template below. // Declare a function template above.
template <classT> classActor { // Declare a friend which is a overload function template of the input operator of class "Actor". // Declare a friend which is a overload function of the input operator of class "Team". private: int id; char name[10]; T hp; T atk; T def; public: bool heal; Actor(int i = 0, bool h = false): id(i), heal(h) {} };
classTeam { // Declare a friend, three private data members and define a public constructor. };
intmain(){ // Declare two arrays below. char waste[100], test; int threshold, i; // Declare two arrays above. // Write some code below to read files. Do not define new objects unless file stream objects. cout << "Standard (%): "; cin >> threshold; Team team(intActor, floatActor, threshold); ofstream fout("team.txt"); fout << team; fout.close(); return0; }
// Define the overload function template of the input operator of class "Actor".
// Define the overload function of the input operator of class "Team".
Additional Files
actors_int.txt
1 2 3 4 5 6 7 8 9 10 11 12
ID Name HP ATK DEF 1 Wilson 55 15 30 2 Carl 58 28 21 healer 3 Emma 65 25 28 healer 4 Warren 84 18 18 5 Larissa 79 16 13 6 Edith 54 13 24 7 Kevin 94 12 14 8 James 62 20 18 9 Sophia 82 22 14 10 Solomon 66 10 23
actors_float.txt
1 2 3 4 5 6 7 8 9 10 11 12
ID Name HP ATK DEF 1 Ashley 73.278 27.342 19.882 2 Leon 66.054 27.828 29.293 healer 3 Barry 62.963 26.368 11.124 4 Benson 61.781 16.626 28.525 5 May 84.577 24.367 21.595 6 Albert 98.882 27.505 29.476 7 Bruce 86.719 22.804 23.628 8 Joyce 63.356 23.636 18.379 9 Paul 79.968 27.674 16.616 healer 10 Ivy 86.747 29.786 28.03
team.txt while threshold is 60
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
ID Name HP ATK DEF 1 Carl 582821 healer 2 Emma 652528 healer 3 Warren 841818 7 James 622018 5 Ashley 73.27827.34219.882 6 Leon 66.05427.82829.293 healer 7 Benson 61.78116.62628.525 8 May 84.57724.36721.595 9 Albert 98.88227.50529.476 10 Bruce 86.71922.80423.628 11 Joyce 63.35623.63618.379 12 Paul 79.96827.67416.616 healer 13 Ivy 86.74729.78628.03
/// /// @file 20-operator-overloads.cc /// @author Lucis Urbe /// @copyright Shanghai Jiao Tong University, 2019 /// @date January 12, 2024 /// @version 0.2 /// @brief The use of fstream objects. /// @note Do not moidify or write more code unless allowed in /// the limited places (see comments). ///
#include<iostream> #include<fstream> #define NUM 20 usingnamespace std;
classTeam; template <classT> classActor; // Declare a function template below. template <classT> ifstream &operator>>(ifstream&, Actor<T>&); // Declare a function template above.
template <classT> classActor { // Declare a friend which is a overload function template of the input operator of class "Actor". template <classType> friend ifstream &operator>>(ifstream&, Actor<Type>&); // // Declare a friend which is a overload function of the input operator of class "Team". friend ofstream &operator<<(ofstream&, Team&); // private: int id; char name[10]; T hp; T atk; T def; public: bool heal; Actor(int i = 0, bool h = false): id(i), heal(false) {} // heal(h)? };
classTeam { // Declare a friend, three private data members and define a public constructor. friend ofstream &operator<<(ofstream&, Team&); private: Actor<int> finalIntActor[NUM]; Actor<float> finalFloatActor[NUM]; int finalThreshold; public: Team(Actor<int>* intActor, Actor<float>* floatActor, int threshold) { for (int i = 0; i < NUM; i++) { finalIntActor[i] = intActor[i]; finalFloatActor[i] = floatActor[i]; } finalThreshold = threshold; } // };
intmain(){ // Declare two arrays below. Actor<int> intActor[NUM]; Actor<float> floatActor[NUM]; // Declare two arrays above. char waste[100], test; int threshold, i; // Write some code below to read files. Do not define new objects unless file stream objects. ifstream finInt("actors_int.txt"), finFloat("actors_float.txt"); if (!finInt) { cout << "***Invalid input file \"actors_int.txt\". The program now exits.***" << endl; return-1; } if (!finFloat) { cout << "***Invalid input file \"actors_float.txt\". The program now exits.***" << endl; return-2; } finInt >> waste >> waste >> waste >> waste >> waste; for (i = 0; !finInt.eof() && i < NUM; i++) { finInt >> intActor[i]; finInt.get(test); if (test == '\t') { intActor[i].heal = true; finInt >> waste; } } finFloat >> waste >> waste >> waste >> waste >> waste; for (i = 0; !finFloat.eof() && i < NUM; i++) { finFloat >> floatActor[i]; finFloat.get(test); if (test == '\t') { floatActor[i].heal = true; finFloat >> waste; } } // cout << "Standard (%): "; cin >> threshold; Team team(intActor, floatActor, threshold); ofstream fout("team.txt"); fout << team; fout.close(); return0; }
// Define the overload function template of the input operator of class "Actor". template <classT> ifstream &operator>>(ifstream& input, Actor<T>& target) { input >> target.id >> target.name >> target.hp >> target.atk >> target.def; return input; } //
// Define the overload function of the input operator of class "Team". ofstream &operator<<(ofstream& output, Team& target) { output << "ID\tName\tHP\tATK\tDEF\n"; int i, j, flag; for (i = j = flag = 0; i < NUM && target.finalIntActor[i].id == i + 1; i++) { if (target.finalIntActor[i].hp > target.finalThreshold) flag++; if (target.finalIntActor[i].atk > target.finalThreshold / 3) flag++; if (target.finalIntActor[i].def > target.finalThreshold / 3) flag++; if (target.finalIntActor[i].heal) flag++; if (flag >= 3) { j++; output << i << '\t' << target.finalIntActor[i].name << '\t' << target.finalIntActor[i].hp << '\t' << target.finalIntActor[i].atk << '\t' << target.finalIntActor[i].def; if (target.finalIntActor[i].heal) output << "\thealer"; output << '\n'; } flag = 0; } for (i = flag = 0; i < NUM && target.finalFloatActor[i].id == i + 1; i++) { if (target.finalFloatActor[i].hp > target.finalThreshold) flag++; if (target.finalFloatActor[i].atk > target.finalThreshold / 3) flag++; if (target.finalFloatActor[i].def > target.finalThreshold / 3) flag++; if (target.finalFloatActor[i].heal) flag++; if (flag >= 3) { output << ++j << '\t' << target.finalFloatActor[i].name << '\t' << target.finalFloatActor[i].hp << '\t' << target.finalFloatActor[i].atk << '\t' << target.finalFloatActor[i].def; if (target.finalFloatActor[i].heal) output << "\thealer"; output << '\n'; } flag = 0; } return output; } //
Conclusion
The article overall reviews the basic skills the first learners needed in C++. It is definitely beneficial to the following learning of computer science if all the codes above are comprehended and can be skilledly rewritten.