diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/2025-2026-1_历次作业_鲍钰.mdx b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/2025-2026-1_历次作业_鲍钰.mdx new file mode 100644 index 0000000..f1f5115 --- /dev/null +++ b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/2025-2026-1_历次作业_鲍钰.mdx @@ -0,0 +1,1535 @@ +--- +title: oopcpp实践2025-2026-1全作业 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +## 作业 + +### 1. ClassDraw + +#### 题目 + +![作业1](./images/25-26-1-hw1.png) + +#### 参考答案 + + + +```cpp title="Draw.h" +#pragma once + +/* + * @Description: 绘制类 +*/ +class Draw +{ +public: + Draw(char what, int down, int across); + void DrawWall(); + void DrawBox(); + void DrawTriangle(); +private: + char what; + int down; + int across; +}; +``` + + + +```cpp title="Draw.cpp" +#include "Draw.h" +#include +#include + +/* + * @Description: 绘制类的构造函数 + * @param {char} what 绘制的字符 + * @param {int} down 绘制的行数 + * @param {int} across 绘制的列数 +*/ +Draw::Draw(char what, int down, int across) { + assert(down >= 0 && across >= 0 && "down or across should >= 0 !"); // 断言,确保 down 和 across 大于等于 0 + this->what = what; + this->down = down; + this->across = across; +} + +/* + * @Description: 绘制墙 +*/ +void Draw::DrawWall() { + for (int i = 0; i < this->down; i++) { + for (int j = 0; j < this->across; j++) { + std::cout << this->what; + } + std::cout << std::endl; + } +} + +/* + * @Description: 绘制盒子 +*/ +void Draw::DrawBox() { + for (int i = 0; i < this->down; i++) { + for (int j = 0; j < this->across; j++) { + if (i != 0 && i != down - 1 && j != 0 && j != across - 1) { + std::cout << " "; + } + else { + std::cout << this->what; + } + } + std::cout << std::endl; + } +} + +/* + * @Description: 绘制三角形 +*/ +void Draw::DrawTriangle() { + int h = down > across ? down : across; + for (int i = 0; i < h; i++) { + for (int j = 0; j < i+1; j++) { + std::cout << this->what; + } + std::cout << std::endl; + } +} +``` + + + +```cpp title="main.cpp" +// file encode: UTF-8 +#include "Draw.h" +#include +#include + + +const std::set TYPES = { -1,1,2,3 }; // 合法的绘制类型 + +/* + * @Description: 主函数 +*/ +int main() +{ + char what = ' '; + int across = 0, down = 0, type = 0; + while (true) { + std::cout << "Please input the shape you want to draw: 1-wall, 2-box, 3-triangle, -1 for end" << std::endl; + std::cin >> type; + if (TYPES.count(type)) { + if (type == -1) { + return 0; + } + else { + std::cout << "input the letter to fill the shape" << std::endl; + std::cin >> what; + std::cout << "height" << std::endl; + std::cin >> down; + std::cout << "width" << std::endl; + std::cin >> across; + if (down < 0 || across < 0) { + std::cout << "height and width should bigger than 0" << std::endl; + continue; + } + Draw draw(what, down, across); + switch (type) { + case 1: + draw.DrawWall(); + break; + case 2: + draw.DrawBox(); + break; + case 3: + draw.DrawTriangle(); + break; + } + } + } + else { + std::cout << "illegal input, please input again!" << std::endl; + } + } + return 0; +} +``` + + + +### 2. ClassDecrypt + +#### 题目 + +![作业2-1](./images/25-26-1-hw2-1.png) + +![作业2-2](./images/25-26-1-hw2-2.png) + +#### 参考答案 + +```cpp title="main.cpp" +#include +#include + +class Decrypt { + std::string s; + int key; +public: + Decrypt(); + Decrypt(std::string s,int key); + int GetKey(); + void PrintKey(); + void GetString(); + void Print(); + void PrintAnswer(); +}; + +Decrypt::Decrypt() { // 默认初始化 + this->s="hello,world!"; + this->key=1; +} + +Decrypt::Decrypt(std::string s,int key) { // 按照给定的s与key初始化 + this->s=s; + this->key=key; +} + +int Decrypt::GetKey() { // 获取key值 + std::cout << "请输入key值(整数【1,10】之间):\n"; + std::string num; // 采用string读入提高代码健壮性 + getline(std::cin,num); // 使用getline避免本行输入中出现空格污染后续输入 + if(num == "10") { // 特殊判断输入为10的情况 + this -> key = 10; + return this -> key; + } + else if(num.size() == 1 && num[0]>='1' && num[0] <= '9') { // 如果输入合法,改变key值 + this->key = num[0] - '0'; + return this->key; + + } + else { // 输入非法,输出提示 + std::cout << "输入的数值不对,key没有改变。\n"; + return 0; + } +} + +void Decrypt::PrintKey() { // 输出当前key值 + std::cout << "key值是:" << this -> key << '\n'; + if(this -> key == 10) { // 如果key在上一步被更改为10,终止程序 + exit(0); + } + return; +} + + +void Decrypt::GetString() { // 获取明文字符串 + std::cout << "请输入明文字符串:\n"; + std::string str; + getline(std::cin,str); // 采用getline防止无法读入明文字符串中潜在的空格 + this->s=str; + return ; +} + +void Decrypt::Print() { // 输出明文字符串 + std::cout << "明文字符串是:"; + std::cout << this->s << '\n'; + return ; +} + +void Decrypt::PrintAnswer() { // 加密字符串 + for(int i = 0; i < this->s.size(); i++) { // 加密并修改字符串 + if(this->s[i] >= 'a' && this->s[i] <= 'z') { + this->s[i] -= key; + } + else if(this->s[i] >= 'A' && this->s[i] <= 'Z') { + this->s[i] -= key; + } + } + std::cout << "加密后的密文字符串是:" << this -> s << '\n'; // 在此处输出加密字符串 + return ; +} + +int main() { + Decrypt test; + while(true) { // 循环在PrintKey()函数中key==10的情况下终止 + test.GetKey(); + test.PrintKey(); + test.GetString(); + test.Print(); + test.PrintAnswer(); + } + return 0; +} +``` + +> 教师批语: +> +> 程序的退出逻辑被放在了 PrintKey函数中,很怪。 +> 一个更合理的做法是在 main函数的循环中检查 GetKey的返回值,并决定是否退出。 + +### 3. ClassRandom + +#### 题目 + +![作业3-1](./images/25-26-1-hw3-1.png) + +![作业3-2](./images/25-26-1-hw3-2.png) + +#### 参考答案 + +```cpp title="main.cpp" +#include +#include +#include +#include +#include +#include + +class Random +{ +public: + int type,left, right, adv; //从左至右分别为 操作类型、最小值、最大值、均值 + Random(bool pseudo); + int reseed(); + double random_real(); + int poisson(double mean); + int input_positive_int(); + double input_positive_double(); + std::vector rand6(); + +private: + int seed, multiplier, add_on; +}; + +Random::Random(bool pseudo) // 构造函数 +{ + if (pseudo) + seed = 1; + else + seed = time(NULL) % INT_MAX; + multiplier = 2743; + add_on = 5923; + type = 0; +} + +int Random::reseed() // 种子生长函数 +{ + seed = seed * multiplier + add_on; + return seed; +} + +double Random::random_real() +{ + double max = INT_MAX + 1.0; // INT_MAX = (2)31 -1 + double temp = reseed(); + if (temp < 0) + temp = temp + max; + return temp / max; +} + +int Random::poisson(double mean) +{ + double limit = exp(-mean); + double product = random_real(); + int count = 0; + while (product > limit) + { + count++; + product *= random_real(); + } + return count; +} + +int Random::input_positive_int() // 以字符串形式读入一个正整数 +{ + std::string str; + std::cin >> str; + int res = 0; + for (int i = 0; i < str.size(); i++) + { + if (str[i] >= '0' && str[i] <= '9') + { + res *= 10; + res += str[i] - '0'; + } + else + { + return -1; + } + } + if(res <= 0) res = -1; + return res; +} + +double Random::input_positive_double() // 以字符串形式读入一个小数 +{ + std::string str; + std::cin >> str; + double res = 0, now = 1; + bool dot = false; + for (int i = 0; i < str.size(); i++) + { + if (str[i] == '.') // 判断小数点是否出现过 + { + if (dot) + { + return -1; + } + else + { + dot = true; + } + } + else if (str[i] >= '0' && str[i] <= '9') + { + if(dot) // 处理小数部分 + { + now /= 10; + res += (str[i] - '0') * now; + } + else // 处理整数部分 + { + res *= 10; + res += str[i] - '0'; + } + } + else + { + return -1; + } + } + if(res <= 0) res = -1; + return res; +} + +std::vector Random::rand6() // 生成六个范围内的随机数 +{ + std::vector res(6); + for (int i = 0; i < 6; i++) + { + res[i] = random_real() * (right - left) + left; + } + return res; +} + +int main() +{ + Random r(false); + std::cout << "=====================================\n"; + std::cout << " 泊松分布随机数生成器应用 \n"; + std::cout << "=====================================\n"; + while (r.type != 3) + { + std::cout << "\n"; + std::cout << "请选择操作:\n"; + std::cout << "1. 生成范围内6个随机数\n"; + std::cout << "2. 生成均值多个随机数\n"; + std::cout << "3. 退出\n"; + std::cout << "请输入选项(1-3):"; + r.type = r.input_positive_int(); + + while (r.type < 1 || r.type > 3) // 确保输入类型符合预期 + { // 我承认这么写看起来很丑 + std::cout << "请您输入选项(1-3),为正整数,请重新来!\n"; // 但我一时想不到相对更好的写法 + r.type = r.input_positive_int(); + } + + if (r.type == 1) // 生成区间内六个随机数 + { + std::cout << "请输入最小值(正整数):"; + r.left = r.input_positive_int(); + + while (r.left < 1) + { + std::cout << "请输入最小值(正整数),为正整数,请重新来!\n"; + r.left = r.input_positive_int(); + } + + std::cout << "请输入最大值(正整数):"; + r.right = r.input_positive_int(); + + while (r.right < 1 || r.right < r.left) + { + if (r.right < 1) + std::cout << "请输入最大值(正整数),为正整数,请重新来!\n"; + else if (r.right < r.left) + std::cout << "错误:最小值不能大于最大值!请重新输入最大值(正整数)\n"; + r.right = r.input_positive_int(); + } + + std::vector res = r.rand6(); + + std::cout << "生成[" << r.left << "," << r.right << "]的6个随机数如下:"; + for (int i = 0; i < 6; i++) + { + std::cout << res[i] << (i < 5 ? ", " : "\n"); + } + } + + else if (r.type == 2) // 生成给定均值的泊松分布随机数 + { + std::cout << "请输入概率均值(正实数):\n"; + r.adv = r.input_positive_double(); + + while (r.adv <= 0) + { + std::cout << "请您概率均值(正实数),为正实数,请重新来!\n"; // 此处拼写错误系给定示例程序原文,故原文保留 + r.adv = r.input_positive_double(); + } + + int num; + std::cout << "请输入产生随机整数的个数(正整数):\n"; + num = r.input_positive_int(); + + while (num < 1) { + std::cout << "请您请输入产生随机整数的个数(正整数),为正整数,请重新来!\n"; + num = r.input_positive_int(); + } + + long long sum = 0; // 计算随机整数之和 + std::cout << "产生随机整数序列:\n"; + for(int i = 0; i < num; i++) + { + int res = r.poisson(r.adv); + sum += res; + std::cout << res << ' '; + } + // 示例程序计算均值似乎有误,已修复此问题 + std::cout << "\n随机整数序列的平均值是:" << (double)sum/num << '\n'; + } + } + std::cout << "感谢使用泊松分布随机数生成器应用!\n"; + return 0; +} +``` + +> 教师批语: +> +> rand6 函数中, +> 生成随机数的公式为 random_real() * (right - left) + left, +> 这样生成的随机数范围实际上是 [left, right),永远无法生成最大值 right + +### 4. ClassTime + +#### 题目 + +![作业4-1](./images/25-26-1-hw4-1.png) + +![作业4-2](./images/25-26-1-hw4-2.png) + +#### 参考答案 + +```cpp title="main.cpp" +#include +#include +#include + +class TimeType +{ +public: + void Set(int hours, int minutes, int seconds); + void Increment(); + void Write() const; + bool Equal(TimeType otherTime) const; + bool Lessthan(TimeType otherTime) const; + TimeType(int initHrs, int initMins, int initSecs); + TimeType(); + bool Overlap(); + +private: + int hrs; + int mins; + int secs; +}; + +void TimeType::Set(int hours, int minutes, int seconds) // 将函数参数赋给类中的变量 +{ + this->hrs = hours; + this->mins = minutes; + this->secs = seconds; + return; +} + +void TimeType::Increment() // 让类增加一秒 +{ + this->secs++; + if (this->secs == 60) // 处理 60 秒 -> 1 分钟进位 + { + this->secs = 0; + this->mins++; + } + if (this->mins == 60) // 处理 60 分钟 -> 1 小时进位 + { + this->mins = 0; + this->hrs++; + } + if (this->hrs == 24) // 处理 24 小时 -> 1 天进位 + { + this->hrs = 0; + } + return; +} + +void TimeType::Write() const +{ + if (this->hrs == 12 || this->hrs == 0) // 特殊处理 0 点和 12 点 + printf("12"); + else //输出当前小时 + printf("%02d", this->hrs%12); + printf(":%02d:%02d\n", this->mins, this->secs); // 以保留两位有效数字形式输出当前分钟与秒 + return; +} + +bool TimeType::Equal(TimeType otherTime) const // 当且仅当小时,分钟,秒三个变量均相等的时候返回 True +{ + return this->hrs == otherTime.hrs && + this->mins == otherTime.mins && + this->secs == otherTime.secs; +} + +bool TimeType::Lessthan(TimeType otherTime) const // 将类中时间转换为自00:00:00过去了多少秒,然后比较大小,只能比较同一天内的时间 +{ + return (this->hrs * 3600 + this->mins * 60 + this->secs) < (otherTime.hrs * 3600 + otherTime.mins * 60 + otherTime.secs); +} + +TimeType::TimeType(int initHrs, int initMins, int initSecs) // 构造函数 +{ + this->hrs = initHrs; + this->mins = initMins; + this->secs = initSecs; +} + +TimeType::TimeType() // 构造函数 +{ + this->hrs = 0; + this->mins = 0; + this->secs = 0; +} + +bool TimeType::Overlap() // 判断三个指针是否重合 +{ + return this->mins == this->secs && this->mins / 12 + this->hrs % 12 * 5 == this->mins; +} + +int main() +{ + TimeType beg(9, 23, 23), end(21, 23, 23); + int num = 0; + for (TimeType i = beg; !i.Equal(end); i.Increment()) // 考虑到可能需要更换参数处理跨天的情况,故采用了 !!i.Equal(end) 而非 i.Increment() 作为循环条件 + { + if (i.Overlap()) + { + std::string s; // 作为吞掉输入的临时变量,无实际意义 + num++; // 计算当前是第多少次重合 + std::cout << "-------------------------------------\n"; //参考示例程序,输出上分割线 + std::cout << "第" << num << "次重合,重合时间:"; + i.Write(); + std::cout << "-------------------------------------\n"; + std::getline(std::cin, s); // 根据实际测试,示例程序应该是采用的getchar(),但是出于美观性的考虑,本处采用了getline() + } + } + return 0; +} +``` + +### 5. CBrowser + +#### 题目 + +![作业5-1](./images/25-26-1-hw5-1.png) + +![作业5-2](./images/25-26-1-hw5-2.png) + +#### 参考答案 + + + +```cpp title="brouser.h" +template +struct Node +{ + // data members + Node_entry entry; + Node *next; + Node *back; + // constructors + Node(); + Node(Node_entry item, Node *link_back = 0, Node *link_next = 0); + ~Node(); +}; + +template +class CBrowser +{ +private: + // data members + Node *current; // 当前游标指针 +public: + // constructors + bool CanForward(); // 可以继续往前 + bool Forward(); // 前进一个节点 + bool CanBack(); // 可以继续后退 + bool Back(); // 后退一个节点 + void NewSite(Node_entry site); // 将新的site插入到current当前位置的后面 + Node *GetCurrent(); // 获得当前游标指针current + CBrowser(); // 缺省构造,空链表 + ~CBrowser(); // 析构,释放所有节点内存 +}; + +template +Node::Node() +{ + this->entry = ""; + this->back = nullptr; + this->next = nullptr; +} + +template +Node::Node(Node_entry item, Node *link_back, Node *link_next) +{ + this->entry = item; + this->back = link_back; + this->next = link_next; +} + +template // 递归删除此节点及其所有后继节点 +Node::~Node() +{ + if (this->next != nullptr) + { + delete this->next; + } +} + +template // 检测当前节点的next指针是否为空以判断是否存在后继节点 +bool CBrowser::CanForward() +{ + return (this->current->next != nullptr); +} + +template +bool CBrowser::Forward() +{ + if (this->CanForward()) + { + this->current = this->current->next; + return true; + } + else + { + return false; + } +} + +template // 采用了含头节点的双向链表 +bool CBrowser::CanBack() // 故检测当前节点的back指针的back指针是否为空检测该节点前驱节点是否为头节点 +{ // 等价于检测该节点是否存在前驱节点 + return (this->current->back->back != nullptr); +} + +template +bool CBrowser::Back() +{ + if (this->CanBack()) + { + this->current = this->current->back; + return true; + } + else + { + return false; + } +} + +template +void CBrowser::NewSite(Node_entry site) +{ + delete this->current->next; // 先删除当前节点的所有后继节点 + Node *newSite = new Node(site, this->current, nullptr); + newSite->entry = site; // 然后使当前节点的后继节点为新节点 + this->current->next = newSite; // 设定指针 + this->current = newSite; // 将当前节点转移至后继节点 +} + +template +Node *CBrowser::GetCurrent() +{ + return this->current; +} + +template +CBrowser::CBrowser() +{ + current = new Node; +} + +template +CBrowser::~CBrowser() +{ + delete this->current; +} +``` + + +```cpp title="main.cpp" +#include +#include +#include "brouser.h" + +int main() +{ + std::cout << "请输入浏览器命令:V(访问新网站),F(前进),B(后退),X(退出)\n"; + CBrowser log; // 创建浏览器历史记录链表 + char command = 0; // 存储当前指令 + while (command != 'X') + { + std::string input; + getline(std::cin, input); // 使用getline()读取字符串作为指令 + command = input.front(); // 取字符串首字符做指令模糊匹配 + + if (command >= 'a' && command <= 'z') // 处理大小写敏感 + { + command -= 'a'; + command += 'A'; + } + + std::string website; + switch (command) + { + case 'V': + std::cout << "请输入新的网址:"; + getline(std::cin, website); // 使用getline()读入新网址 + log.NewSite(website); + std::cout << "当前网址是:" << log.GetCurrent()->entry << '\n'; + break; + + case 'F': + if (log.Forward()) + { + std::cout << "当前网址是:" << log.GetCurrent()->entry << '\n'; + } + else + { + std::cout << "无法前进!\n"; + } + break; + + case 'B': + if (log.Back()) + { + std::cout << "当前网址是:" << log.GetCurrent()->entry << '\n'; + } + else + { + std::cout << "无法后退!\n"; + } + break; + + case 'X': + break; + + default: + std::cout << "请输入合法的浏览器命令:V(访问新网站),F(前进),B(后退),X(退出)\n"; // 处理读入非法命令的情况 + break; + } + } + return 0; +} +``` + + + +### 6. CTypes + +#### 题目 + +![作业6-1](./images/25-26-1-hw6-1.png) + +![作业6-2](./images/25-26-1-hw6-2.png) + +#### 参考答案 + +```cpp title="main.cpp" +#include + +using namespace std; + +long long input_int(string str) // 以字符串形式读入一个正整数,从之前写的随机数类作业中拿过来的 +{ + long long res = 0; + long long i = 0; + bool negative = false; + if (str.front() == '-') // 处理负号 + { + negative = true; + i++; + } + for (; i < str.size(); i++) + { + if (str[i] >= '0' && str[i] <= '9') + { + res *= 10; + res += str[i] - '0'; + } + else //非法值一律返回0,在函数内再进行判断 + { + return 0; + } + } + return negative ? -res : res; +} + +class CTypes +{ +public: + CTypes(); // 缺省构造函数,所有成员初始化为0 + CTypes(int n, unsigned int i, char c, unsigned char u, bool b); // 构造函数,所有成员初始化为形参 + void setValue(); // 设置内部成员数据数值 + void printValue(); // 输出内部成员数据数值 + void printDeep(); // 输出所有内部成员数据底层补码的存放信息 + +private: + void printBinary(void *var, size_t size); // 打印指针var指向任意变量(字节数为size)的底层二进制表示 + // size_t 是一个无符号整数类型,32位系统unsigned int(4字节)64位系统unsigned long(8字节) + // void * 是一种特殊的指针类型,称为 "无类型指针" 或 "泛型指针",在解引用,或者+-操作之前,必须将其转换为具体的指针类型。 + + // 内部成员: + int n; + unsigned int i; + char c; + unsigned char u; + bool b; +}; + +CTypes::CTypes() //缺省构造 +{ + this->n = 0; + this->i = 0; + this->c = '\0'; + this->u = '\0'; + this->b = false; +} + +CTypes::CTypes(int n, unsigned int i, char c, unsigned char u, bool b) //给定值构造 +{ + this->n = n; + this->i = i; + this->c = c; + this->u = u; + this->b = b; +} + +void CTypes::setValue() +{ + string str; + long long temp; + cout << "请输入整数n:\n"; + while (1) + { + getline(cin, str); + temp = input_int(str); + if (temp == 0 && str != "0") //此处判断返回值为0是读入了非法值还是读入了0 + { + cout << "请您输入整数,请重新来!\n"; + } + else + { + this->n = temp; + break; + } + } + + cout << "请输入非负整数i:\n"; + while (1) + { + getline(cin, str); + temp = input_int(str); + if (temp == 0 && str != "0") + { + cout << "请您输入非负整数,请重新来!\n"; + } + else if (temp < 0) //返回负数的时候同样作为非法值处理 + { + cout << "请您输入非负整数,请重新来!\n"; + } + else + { + this->i = temp; + break; + } + } + + cout << "请输入字符c:\n"; // 按照样例程序,此处输入字符串时保留第一个字符 + getline(cin, str); + this->c = str.front(); + + cout << "请输入【0,255】闭区间的整数for unsigned char u:\n"; + while (1) + { + getline(cin, str); + temp = input_int(str); + if (temp == 0 && str != "0") + { + cout << "请您输入【0,255】闭区间的整数,请重新来!\n"; + } + else if (temp < 0 || temp > 255) //处理返回范围外的非法值 + { + cout << "请您输入【0,255】闭区间的整数,请重新来!\n"; + } + else + { + this->u = temp; + break; + } + } + + cout << "请输入布尔类型数值b,只能为0或1:\n"; + while (1) //因为布尔类型情形简单,只需要判断两种情况,便不调用字符串转整数函数了 + { + getline(cin, str); + if (str == "0") + { + this->b = false; + break; + } + else if (str == "1") + { + this->b = true; + break; + } + else + { + cout << "请您输入布尔类型数值b,只能为0或1,请重新来!\n"; + } + } + + return; +} + +void CTypes::printValue() //打印变量 +{ + cout << "内部成员数值为:" << endl; + cout << "整数n数值为:" << this -> n << endl; + cout << "无符号整数i数值为:" << this -> i << endl; + cout << "字符c数值为:" << this -> c << endl; + cout << "无符号字符u数值为:" << (int)(this -> u) << endl; //以数值形式打印无符号整数 + cout << "布尔类型b数值为:" << this -> b << endl; + return; +} + +void CTypes::printDeep() +{ + cout << "内部成员底层补码0和1信息为:" << endl; + + cout << "整数" << this->n << "底层补码0和1信息为:"; + this->printBinary(&(this->n), sizeof(this->n)); + cout << endl; + + cout << "无符号" << this->i << "底层补码0和1信息为:"; + this->printBinary(&(this->i), sizeof(this->i)); + cout << endl; + + cout << "字符" << this->c << "底层补码0和1信息为:"; + this->printBinary(&(this->c), sizeof(this->c)); + cout << endl; + + cout << "无符号字符" << (int)(this->u) << "底层补码0和1信息为:"; //这里同样以数值形式打印无符号整数 + this->printBinary(&(this->u), sizeof(this->u)); + cout << endl; + + cout << "布尔类型" << this->b << "底层补码0和1信息为:"; + this->printBinary(&(this->b), sizeof(this->b)); + cout << endl; + + return; +} + +void CTypes::printBinary(void *var, size_t size) +{ + unsigned long long now = (1LL << (size*8-1)); // 将 now 设为最高位为 1 ,其余位为0的形式 + unsigned long long value; + switch(size) { // 以对应的无符号类型读取 var 指向的值,便于后续位运算处理 + case 1: + value = *((unsigned char*)var); + break; + case 2: + value = *((unsigned short*)var); + break; + case 4: + value = *((unsigned long*)var); + break; + case 8: + value = *((unsigned long long*)var); + break; + default: + value = (1LL << 63); + } + int num = 0; + while(now) { + cout << (bool)(now&value); + num ++; + now >>=1; // 通过 now 每次右移自左向右打印底层存储 + if(num == 8) // 字节之间以空格隔开 + { + cout << ' '; + num = 0; + } + } + return; +} + +int main() +{ + CTypes t1; + CTypes t2(-10, 10, 'K', 200, 1); + cout << "注意,整数在底层是按照补码存放,正整数的原码 = 反码 = 补码;" << endl; + cout << "负数的反码是原码符号位不变,数值位取反,补码是反码加1。" << endl; + cout << "下面是缺省构造成员底层内部信息:" << endl; + t1.printDeep(); + cout << "下面是t2(-10,10,'K',200,1)构造后,成员底层内部信息:" << endl; + t2.printDeep(); + cout << endl; + +label1: + string input = ""; + cout << "请选择操作:" << endl; + cout << "1. 设置类所有内部成员数值,并回显" << endl; + cout << "2. 打印类所有成员内部底层0和1表示信息" << endl; + cout << "3. 退出" << endl; + cout << "请输入选项 (1-3):"; + while (input != "3") + { + getline(cin, input); + if (input == "1") + { + t1.setValue(); + cout << endl; + cout << "信息回显:" << endl; + t1.printValue(); + cout << endl; + goto label1; // 使用 goto 来重新打印默认信息 + } + else if (input == "2") + { + t1.printDeep(); + cout << endl; + goto label1; + } + else if (input == "3") + { + break; + } + else + { + cout << "请您输入选项 (1-3),为正整数,请重新来!" << endl; + } + } + return 0; +} +``` + +### 期末大作业 + +#### 题目 + +Move.h + +![作业7-1](./images/25-26-1-hw7-1.png) + +MyStack.h + +![作业7-2](./images/25-26-1-hw7-2.png) + +Board.h + +![作业7-3](./images/25-26-1-hw7-3.png) + +1. 当输入无效棋谱文件名称时,程序要求人自行和电脑对战,运行效果如下图 + +![作业7-4](./images/25-26-1-hw7-4.png) + +2. 当输入初学者棋谱beginer.txt时,运行效果如下图 + +![作业7-5](./images/25-26-1-hw7-5.png) + +![作业7-6](./images/25-26-1-hw7-6.png) + +3. 当输入高手棋谱master.txt时,运行效果如下图 + +![作业7-7](./images/25-26-1-hw7-7.png) + +![作业7-8](./images/25-26-1-hw7-8.png) + + + +```text title="beginner.txt" +0 0 +0 1 +0 2 +1 0 +1 1 +1 2 +2 0 +2 1 +2 2 +``` + + +```text title="master.txt" +1 1 +2 0 +1 2 +0 1 +``` + + + +#### 参考答案 + + + +```cpp title="Move.h" +class Move +{ +public: + Move(); + Move(int r, int c); + int row; + int col; +}; + +Move::Move() +{ + row = -1; + col = -1; +} + +Move::Move(int r, int c) +{ + row = r; + col = c; +} +``` + + +```cpp title="MyStack.h" +enum Error_code +{ + underflow, + overflow, + success +}; + +const int maxstack = 10; + +template +class MyStack +{ +public: + MyStack(); + bool empty() const; + Error_code pop(); + Error_code top(Stack_entry &item) const; + Error_code push(const Stack_entry &item); + +private: + int count; + Stack_entry entry[maxstack]; +}; + +template +MyStack::MyStack() +{ + count = 0; +} + +template +bool MyStack::empty() const +{ + return count <= 0; +} + +template +Error_code MyStack::pop() +{ + if(empty()) + { + return underflow; + } + count--; + return success; +} + +template +Error_code MyStack::top(Stack_entry &item) const +{ + if(empty()) + { + return underflow; + } + item = entry[count - 1]; + return success; +} + +template +Error_code MyStack::push(const Stack_entry &item) +{ + if(count >= maxstack) + { + return overflow; + } + entry[count] = item; + count++; + return success; +} +``` + + +```cpp title="Board.h" +#include +#include "Move.h" +#include "MyStack.h" + +class Board +{ +public: + Board(); + bool done() const; + void print() const; + void instructions() const; + bool better(int value, int old_value) const; + bool ValidStep(Move try_it) const; + void play(Move try_it); + int worst_case() const; + int evaluate() const; + int legal_moves(MyStack &moves) const; + int the_winner() const; + +private: + int squares[3][3]; + int moves_done; +}; + +Board::Board() +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + squares[i][j] = 0; + moves_done = 0; +} + +bool Board::done() const +{ + return moves_done == 9 || the_winner() > 0; +} + +void Board::print() const +{ + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + std::cout << " " << squares[i][j]; + } + std::cout << '\n'; + } + std::cout << '\n'; +} + +void Board::instructions() const +{ + std::cout << "This is a Tic-Tac-Toe game. Wait for computer going...\n"; +} + +bool Board::ValidStep(Move try_it) const +{ + return (squares[try_it.row][try_it.col] == 0); +} + +void Board::play(Move try_it) +{ + squares[try_it.row][try_it.col] = moves_done % 2 + 1; + moves_done++; +} + +int Board::the_winner() const +{ + for (int i = 0; i < 3; i++) + { + if (squares[i][1] != 0 && + squares[i][1] == squares[i][0] && + squares[i][1] == squares[i][2]) + return squares[i][1]; + if (squares[1][i] != 0 && + squares[1][i] == squares[0][i] && + squares[1][i] == squares[2][i]) + return squares[1][i]; + } + if (squares[1][1] != 0) + { + if (squares[1][1] == squares[0][0] && + squares[1][1] == squares[2][2]) + return squares[1][1]; + if (squares[1][1] == squares[0][2] && + squares[1][1] == squares[2][0]) + return squares[1][1]; + } + return 0; +} + +int Board::legal_moves(MyStack &moves) const +{ + int count = 0; + while (!moves.empty()) + moves.pop(); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (squares[i][j] == 0) + { + moves.push(Move(i, j)); + count++; + } + return count; +} + +int Board::evaluate() const +{ + int winner = the_winner(); + if(winner == 1) return 10-moves_done; + else if(winner == 2) return moves_done-10; + else return 0; +} + +bool Board::better(int value, int old_value) const +{ + if(moves_done%2) return valueold_value; +} + +int Board::worst_case() const +{ + if(moves_done%2) return 10; + else return -10; +} +``` + + +```cpp title="main.cpp" +#include "Board.h" +#include +#include +#include +#include +#include + +int look_ahead(const Board &game, int depth, Move &recommended) +{ + if (game.done() || depth == 0) + return game.evaluate(); + else + { + MyStack moves; + game.legal_moves(moves); + int value, best_value = game.worst_case(); + while (!moves.empty()) + { + Move try_it, reply; + moves.top(try_it); + Board new_game = game; + new_game.play(try_it); + value = look_ahead(new_game, depth - 1, reply); + if (game.better(value, best_value)) + { + best_value = value; + recommended = try_it; + } + moves.pop(); + } + return best_value; + } +} + +void play(std::vector> rem) +{ + Board game; + Move recommended; + int x, y; + int i = 9; + int now = 0; + game.instructions(); + while (!game.done()) + { + look_ahead(game, i, recommended); + game.play(recommended); + std::cout << "Computer:\n"; + game.print(); + if (game.done()) + break; + std::cout << "Your turn:\n"; + if (now < rem.size()) + { + x = rem[now].first; + y = rem[now].second; + } + else + { + std::cout << "X:"; + std::cin >> x; + std::cout << "Y:"; + std::cin >> y; + } + Move me(x, y); + game.play(me); + game.print(); + i--; + } + if (game.the_winner() == 1) + std::cout << "Game over with computer win.\n"; + else if (game.the_winner() == 2) + std::cout << "Game over with you win.\n"; + else + std::cout << "Game over with a draw.\n"; +} + +std::vector> read(std::string file) +{ + freopen(file.c_str(),"r",stdin); + std::string line; + std::vector> rem; + while(std::getline(std::cin,line)) + { + if(line.size()==0) break; + std::istringstream record(line); + int x,y; + record >> x >> y; + rem.push_back({x,y}); + } + freopen("CON","r",stdin); + return rem; +} + +int main() +{ + std::string filename; + std::cout << "Please input the chess file name:\n"; + std::cin >> filename; + std::ifstream file(filename); + std::vector> rem; + if(file.good()) + { + rem = read(filename); + } + else + { + std::cout << "** Can't open input file **\n"; + std::cout << "Please input by youself."; + } + play(rem); + return 0; +} +``` + + \ No newline at end of file diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/README.md b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/README.md new file mode 100644 index 0000000..095c3c5 --- /dev/null +++ b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/README.md @@ -0,0 +1,14 @@ +--- +title: 面向对象程序设计实践(基于C++) +description: "课程代码: SE2414" +--- + +## 2025-2026 学年上学期 + +### 鲍钰 + +非常简单,没上理论课也可以轻松完成作业的程度。 + +但是早八略不友善 + +基本就是上课写一节课的作业,然后最后一节课作业是考试 \ No newline at end of file diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw1.png new file mode 100644 index 0000000..9beea74 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-1.png new file mode 100644 index 0000000..7cad25e Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-2.png new file mode 100644 index 0000000..48caa53 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw2-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-1.png new file mode 100644 index 0000000..8093bdb Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-2.png new file mode 100644 index 0000000..658cc7f Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw3-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-1.png new file mode 100644 index 0000000..b1744dc Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-2.png new file mode 100644 index 0000000..5e60d87 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw4-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-1.png new file mode 100644 index 0000000..bffedd2 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-2.png new file mode 100644 index 0000000..4b22b29 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw5-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-1.png new file mode 100644 index 0000000..3b44c0f Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-2.png new file mode 100644 index 0000000..0ac1724 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw6-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-1.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-1.png new file mode 100644 index 0000000..96b433e Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-1.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-2.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-2.png new file mode 100644 index 0000000..95e055c Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-2.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-3.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-3.png new file mode 100644 index 0000000..cab8d01 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-3.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-4.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-4.png new file mode 100644 index 0000000..4c08588 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-4.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-5.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-5.png new file mode 100644 index 0000000..698ec16 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-5.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-6.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-6.png new file mode 100644 index 0000000..f85c410 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-6.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-7.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-7.png new file mode 100644 index 0000000..a15ec72 Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-7.png differ diff --git a/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-8.png b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-8.png new file mode 100644 index 0000000..678660c Binary files /dev/null and b/docs/undergraduate/软件工程学院/面向对象程序设计实践(基于C++)/images/25-26-1-hw7-8.png differ