├── .gitignore ├── CMakeLists.txt ├── README.md ├── main.cpp └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | GNUmakefile 3 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | project(hellocmake LANGUAGES CXX) 3 | 4 | set(CMAKE_CXX_STANDARD 17) 5 | if (NOT CMAKE_BUILD_TYPE) 6 | set(CMAKE_BUILD_TYPE Debug) 7 | endif() 8 | 9 | add_executable(main main.cpp) 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 高性能并行编程与优化 - 第0x讲的回家作业 2 | 3 | 通过 pull request 提交作业。会批分数,但是: 4 | 5 | 没有结业证书,回家作业仅仅作为评估学习效果和巩固知识的手段,不必为分数感到紧张 :) 6 | 量力而行,只要能在本课中,学到昨天的自己不懂的知识,就是胜利,没必要和别人攀比。 7 | 注意不要偷看别人的作业哦! 8 | 9 | - 课件:https://github.com/parallel101/course 10 | - 录播:https://space.bilibili.com/263032155 11 | 12 | 作业提交时间不限 :) 即使完结了还想交的话我也会看的~ 不过最好在下一讲开播前完成。 13 | 14 | - 如何开 pull request:https://zhuanlan.zhihu.com/p/51199833 15 | - 如何设置 https 代理:https://www.jianshu.com/p/b481d2a42274 16 | 17 | ## 评分规则 18 | 19 | - 完成作业基本要求 50 分(详见下方"作业要求") 20 | - 能够在 PR 描述中用自己的话解释 25 分 21 | - 代码格式规范、能够跨平台 5 分 22 | - 有自己独特的创新点 20 分 23 | - 明显抄袭现象 -100 分 24 | 25 | ## 作业要求 26 | 27 | 修改 main.cpp,改良其中的双链表类 `List`: 28 | 29 | - 避免函数参数不必要的拷贝 5 分 30 | - 修复智能指针造成的问题 10 分 31 | - 改用 `unique_ptr` 10 分 32 | - 实现拷贝构造函数为深拷贝 15 分 33 | - 说明为什么可以删除拷贝赋值函数 5 分 34 | - 改进 `Node` 的构造函数 5 分 35 | 36 | 并通过 `main()` 函数中的基本测试。 37 | 38 | ## 关于内卷 39 | 40 | 如果你把 List 改成了基于迭代器的,或是作为模板 `List`: 41 | 只要是在 **满足作业要求的基础** 上,这是件好事! 42 | 老师会酌情加分,视为“独特的创新点”,但最多不超过 20 分。 43 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* 基于智能指针实现双向链表 */ 2 | #include 3 | #include 4 | 5 | struct Node { 6 | // 这两个指针会造成什么问题?请修复 7 | std::shared_ptr next; 8 | std::shared_ptr prev; 9 | // 如果能改成 unique_ptr 就更好了! 10 | 11 | int value; 12 | 13 | // 这个构造函数有什么可以改进的? 14 | Node(int val) { 15 | value = val; 16 | } 17 | 18 | void insert(int val) { 19 | auto node = std::make_shared(val); 20 | node->next = next; 21 | node->prev = prev; 22 | if (prev) 23 | prev->next = node; 24 | if (next) 25 | next->prev = node; 26 | } 27 | 28 | void erase() { 29 | if (prev) 30 | prev->next = next; 31 | if (next) 32 | next->prev = prev; 33 | } 34 | 35 | ~Node() { 36 | printf("~Node()\n"); // 应输出多少次?为什么少了? 37 | } 38 | }; 39 | 40 | struct List { 41 | std::shared_ptr head; 42 | 43 | List() = default; 44 | 45 | List(List const &other) { 46 | printf("List 被拷贝!\n"); 47 | head = other.head; // 这是浅拷贝! 48 | // 请实现拷贝构造函数为 **深拷贝** 49 | } 50 | 51 | List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? 52 | 53 | List(List &&) = default; 54 | List &operator=(List &&) = default; 55 | 56 | Node *front() const { 57 | return head.get(); 58 | } 59 | 60 | int pop_front() { 61 | int ret = head->value; 62 | head = head->next; 63 | return ret; 64 | } 65 | 66 | void push_front(int value) { 67 | auto node = std::make_shared(value); 68 | node->next = head; 69 | if (head) 70 | head->prev = node; 71 | head = node; 72 | } 73 | 74 | Node *at(size_t index) const { 75 | auto curr = front(); 76 | for (size_t i = 0; i < index; i++) { 77 | curr = curr->next.get(); 78 | } 79 | return curr; 80 | } 81 | }; 82 | 83 | void print(List lst) { // 有什么值得改进的? 84 | printf("["); 85 | for (auto curr = lst.front(); curr; curr = curr->next.get()) { 86 | printf(" %d", curr->value); 87 | } 88 | printf(" ]\n"); 89 | } 90 | 91 | int main() { 92 | List a; 93 | 94 | a.push_front(7); 95 | a.push_front(5); 96 | a.push_front(8); 97 | a.push_front(2); 98 | a.push_front(9); 99 | a.push_front(4); 100 | a.push_front(1); 101 | 102 | print(a); // [ 1 4 9 2 8 5 7 ] 103 | 104 | a.at(2)->erase(); 105 | 106 | print(a); // [ 1 4 2 8 5 7 ] 107 | 108 | List b = a; 109 | 110 | a.at(3)->erase(); 111 | 112 | print(a); // [ 1 4 2 5 7 ] 113 | print(b); // [ 1 4 2 8 5 7 ] 114 | 115 | b = {}; 116 | a = {}; 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | cmake -B build 4 | cmake --build build 5 | build/main 6 | --------------------------------------------------------------------------------