diff --git a/exercises/00_hello_world/main b/exercises/00_hello_world/main new file mode 100755 index 000000000..94ab3fe37 Binary files /dev/null and b/exercises/00_hello_world/main differ diff --git a/exercises/00_hello_world/main.cpp b/exercises/00_hello_world/main.cpp index 8866f3c15..fa454e132 100644 --- a/exercises/00_hello_world/main.cpp +++ b/exercises/00_hello_world/main.cpp @@ -6,6 +6,6 @@ int main(int argc, char **argv) { // TODO: 在控制台输出 "Hello, InfiniTensor!" 并换行 - std::cout : "Hello, InfiniTensor!" + std::endl; + std::cout << "Hello, InfiniTensor!" << std::endl; return 0; } diff --git a/exercises/01_variable&add/main b/exercises/01_variable&add/main new file mode 100755 index 000000000..df520d815 Binary files /dev/null and b/exercises/01_variable&add/main differ diff --git a/exercises/01_variable&add/main.cpp b/exercises/01_variable&add/main.cpp index 5014863fd..71fabf2b4 100644 --- a/exercises/01_variable&add/main.cpp +++ b/exercises/01_variable&add/main.cpp @@ -5,6 +5,7 @@ int main(int argc, char **argv) { // TODO: 补全变量定义并打印加法运算 // x ? + int x = 1; std::cout << x << " + " << x << " = " << x + x << std::endl; return 0; } diff --git a/exercises/02_function/main b/exercises/02_function/main new file mode 100755 index 000000000..affa443a3 Binary files /dev/null and b/exercises/02_function/main differ diff --git a/exercises/02_function/main.cpp b/exercises/02_function/main.cpp index b5eef7f28..be4dcefa3 100644 --- a/exercises/02_function/main.cpp +++ b/exercises/02_function/main.cpp @@ -5,6 +5,7 @@ // NOTICE: 补充由内而外读法的机翻解释 // TODO: 在这里声明函数 +int add(int a, int b); int main(int argc, char **argv) { ASSERT(add(123, 456) == 123 + 456, "add(123, 456) should be 123 + 456"); @@ -16,4 +17,5 @@ int main(int argc, char **argv) { int add(int a, int b) { // TODO: 补全函数定义,但不要移动代码行 + return a + b; } diff --git a/exercises/03_argument¶meter/main b/exercises/03_argument¶meter/main new file mode 100755 index 000000000..110883be6 Binary files /dev/null and b/exercises/03_argument¶meter/main differ diff --git a/exercises/03_argument¶meter/main.cpp b/exercises/03_argument¶meter/main.cpp index 7fb5d3c2f..76136eae6 100644 --- a/exercises/03_argument¶meter/main.cpp +++ b/exercises/03_argument¶meter/main.cpp @@ -8,19 +8,19 @@ void func(int); // TODO: 为下列 ASSERT 填写正确的值 int main(int argc, char **argv) { auto arg = 99; - ASSERT(arg == ?, "arg should be ?"); + ASSERT(arg == 99, "arg should be ?"); std::cout << "befor func call: " << arg << std::endl; func(arg); - ASSERT(arg == ?, "arg should be ?"); + ASSERT(arg == 99, "arg should be ?"); std::cout << "after func call: " << arg << std::endl; return 0; } // TODO: 为下列 ASSERT 填写正确的值 void func(int param) { - ASSERT(param == ?, "param should be ?"); + ASSERT(param == 99, "param should be ?"); std::cout << "befor add: " << param << std::endl; param += 1; - ASSERT(param == ?, "param should be ?"); + ASSERT(param == 100, "param should be ?"); std::cout << "after add: " << param << std::endl; } diff --git a/exercises/04_static/main b/exercises/04_static/main new file mode 100755 index 000000000..05b417dc7 Binary files /dev/null and b/exercises/04_static/main differ diff --git a/exercises/04_static/main.cpp b/exercises/04_static/main.cpp index f107762fa..64f417694 100644 --- a/exercises/04_static/main.cpp +++ b/exercises/04_static/main.cpp @@ -10,10 +10,10 @@ static int func(int param) { int main(int argc, char **argv) { // TODO: 将下列 `?` 替换为正确的数字 - ASSERT(func(5) == ?, "static variable value incorrect"); - ASSERT(func(4) == ?, "static variable value incorrect"); - ASSERT(func(3) == ?, "static variable value incorrect"); - ASSERT(func(2) == ?, "static variable value incorrect"); - ASSERT(func(1) == ?, "static variable value incorrect"); + ASSERT(func(5) == 5, "static variable value incorrect"); + ASSERT(func(4) == 6, "static variable value incorrect"); + ASSERT(func(3) == 7, "static variable value incorrect"); + ASSERT(func(2) == 8, "static variable value incorrect"); + ASSERT(func(1) == 9, "static variable value incorrect"); return 0; } diff --git a/exercises/05_constexpr/main b/exercises/05_constexpr/main new file mode 100755 index 000000000..f4e774cb4 Binary files /dev/null and b/exercises/05_constexpr/main differ diff --git a/exercises/05_constexpr/main.cpp b/exercises/05_constexpr/main.cpp index d1db6c9d8..b0186236e 100644 --- a/exercises/05_constexpr/main.cpp +++ b/exercises/05_constexpr/main.cpp @@ -18,8 +18,8 @@ int main(int argc, char **argv) { // TODO: 观察错误信息,修改一处,使代码编译运行 // PS: 编译运行,但是不一定能算出结果…… - constexpr auto ANS_N = 90; - constexpr auto ANS = fibonacci(ANS_N); + constexpr auto ANS_N = 90; // 编译时必须计算出结果,const只要求值不可变,运行时也可 + const auto ANS = fibonacci(ANS_N); std::cout << "fibonacci(" << ANS_N << ") = " << ANS << std::endl; return 0; diff --git a/exercises/06_array/main b/exercises/06_array/main new file mode 100755 index 000000000..da24e3c59 Binary files /dev/null and b/exercises/06_array/main differ diff --git a/exercises/06_array/main.cpp b/exercises/06_array/main.cpp index 61ed99ec0..f741db8a8 100644 --- a/exercises/06_array/main.cpp +++ b/exercises/06_array/main.cpp @@ -11,13 +11,13 @@ unsigned long long fibonacci(int i) { return 1; default: // TODO: 补全三目表达式缺失的部分 - return ? : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2)); + return arr[i] ? arr[i]: (arr[i] = fibonacci(i - 1) + fibonacci(i - 2)); // 实现记忆化 } } int main(int argc, char **argv) { // TODO: 为此 ASSERT 填写正确的值 - ASSERT(sizeof(arr) == ?, "sizeof array is size of all its elements"); + ASSERT(sizeof(arr) == 90 * sizeof(unsigned long long) , "sizeof array is size of all its elements"); // ---- 不要修改以下代码 ---- ASSERT(fibonacci(2) == 1, "fibonacci(2) should be 1"); ASSERT(fibonacci(20) == 6765, "fibonacci(20) should be 6765"); diff --git a/exercises/07_loop/main b/exercises/07_loop/main new file mode 100755 index 000000000..f0fb1cdd5 Binary files /dev/null and b/exercises/07_loop/main differ diff --git a/exercises/07_loop/main.cpp b/exercises/07_loop/main.cpp index 44fd835cd..461414efa 100644 --- a/exercises/07_loop/main.cpp +++ b/exercises/07_loop/main.cpp @@ -5,9 +5,9 @@ // READ: 纯函数 static unsigned long long fibonacci(int i) { // TODO: 为缓存设置正确的初始值 - static unsigned long long cache[96], cached; + static unsigned long long cache[96]={0,1}, cached = 2; // TODO: 设置正确的循环条件 - for (; false; ++cached) { + for (; cached < 96; ++cached) { cache[cached] = cache[cached - 1] + cache[cached - 2]; } return cache[i]; diff --git a/exercises/08_pointer/main b/exercises/08_pointer/main new file mode 100755 index 000000000..bc9dbdd15 Binary files /dev/null and b/exercises/08_pointer/main differ diff --git a/exercises/08_pointer/main.cpp b/exercises/08_pointer/main.cpp index ba37173f5..202796d08 100644 --- a/exercises/08_pointer/main.cpp +++ b/exercises/08_pointer/main.cpp @@ -5,6 +5,17 @@ bool is_fibonacci(int *ptr, int len, int stride) { ASSERT(len >= 3, "`len` should be at least 3"); // TODO: 编写代码判断从 ptr 开始,每 stride 个元素取 1 个元素,组成长度为 n 的数列是否满足 // arr[i + 2] = arr[i] + arr[i + 1] + + for (int i = 0; i < len - 2; i++) { // len表示元素个数,不是边界 + int a = ptr[i * stride]; + int b = ptr[(i + 1) * stride]; + int c = ptr[(i + 2) * stride]; + + if (c != a + b) { + return false; + } + } + return true; } diff --git a/exercises/09_enum&union/main b/exercises/09_enum&union/main new file mode 100755 index 000000000..2f125d6ad Binary files /dev/null and b/exercises/09_enum&union/main differ diff --git a/exercises/09_enum&union/main.cpp b/exercises/09_enum&union/main.cpp index 3f2cec768..e233db8a4 100644 --- a/exercises/09_enum&union/main.cpp +++ b/exercises/09_enum&union/main.cpp @@ -6,7 +6,7 @@ // 在 `enum` 中定义标识符等价于定义 constexpr 常量, // 这些标识符不需要前缀,可以直接引用。 // 因此 `enum` 定义会污染命名空间。 -enum ColorEnum : unsigned char { +enum ColorEnum : unsigned char { COLOR_RED = 31, COLOR_GREEN, COLOR_YELLOW, @@ -16,7 +16,7 @@ enum ColorEnum : unsigned char { // 有作用域枚举型是 C++ 引入的类型安全枚举。 // 其内部标识符需要带前缀引用,如 `Color::Red`。 // 作用域枚举型可以避免命名空间污染,并提供类型安全保证。 -enum class Color : int { +enum class Color : int { // 如同int /float一样知识取值,31,可以选red,green,yellow,blue Red = COLOR_RED, Green, Yellow, @@ -26,7 +26,7 @@ enum class Color : int { ColorEnum convert_by_pun(Color c) { // READ: // `union` 表示在同一内存位置存储的不同类型的值。 - // 其常见用法是实现类型双关转换,即将一种类型的值转换为另一种无关类型的值。 + // 其常见用法是实现类型双关转换,即将一种类型的值转换为另一种无关类型的值。 // 但这种写法实际上仅在 C 语言良定义,在 C++ 中是未定义行为。 // 这是比较少见的 C++ 不与 C 保持兼容的特性。 // READ: 类型双关 @@ -37,6 +37,7 @@ ColorEnum convert_by_pun(Color c) { TypePun pun; // TODO: 补全类型双关转换 + pun.c = c; return pun.e; } @@ -48,3 +49,5 @@ int main(int argc, char **argv) { ASSERT(convert_by_pun(Color::Blue) == COLOR_BLUE, "Type punning conversion"); return 0; } + + diff --git a/exercises/10_trivial/main b/exercises/10_trivial/main new file mode 100755 index 000000000..97da4521d Binary files /dev/null and b/exercises/10_trivial/main differ diff --git a/exercises/10_trivial/main.cpp b/exercises/10_trivial/main.cpp index 6ba23e48e..acf04c48f 100644 --- a/exercises/10_trivial/main.cpp +++ b/exercises/10_trivial/main.cpp @@ -9,8 +9,27 @@ struct FibonacciCache { // TODO: 实现正确的缓存优化斐波那契计算 static unsigned long long fibonacci(FibonacciCache &cache, int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + // 已经缓存的值 + if (i <= cache.cached) + { + return cache.cache[i]; + } + // 未缓存值 + for (int n = cache.cached; n <= i ; ++n ) + { + if(n == 0) + { + cache.cache[n] = 0; + } + else if(n == 1) + { + cache.cache[n] = 1; + } + else + { + cache.cache[n] = cache.cache[n - 1] + cache.cache[n - 2]; + } + cache.cached = n; } return cache.cache[i]; } @@ -19,7 +38,7 @@ int main(int argc, char **argv) { // TODO: 初始化缓存结构体,使计算正确 // NOTICE: C/C++ 中,读取未初始化的变量(包括结构体变量)是未定义行为 // READ: 初始化的各种写法 - FibonacciCache fib; + FibonacciCache fib ={}; // 结构体需要初始化 ASSERT(fibonacci(fib, 10) == 55, "fibonacci(10) should be 55"); std::cout << "fibonacci(10) = " << fibonacci(fib, 10) << std::endl; return 0; diff --git a/exercises/11_method/main b/exercises/11_method/main new file mode 100755 index 000000000..6ad0f41dc Binary files /dev/null and b/exercises/11_method/main differ diff --git a/exercises/11_method/main.cpp b/exercises/11_method/main.cpp index 0e08e0a36..1ec16445b 100644 --- a/exercises/11_method/main.cpp +++ b/exercises/11_method/main.cpp @@ -6,8 +6,24 @@ struct Fibonacci { // TODO: 实现正确的缓存优化斐波那契计算 unsigned long long get(int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if(i < cached) + { + return cache[i]; + } + for (int n = cached; n <= i;++n) + { + if(n==0) + { + cache[n] = 0; + } + else if (n==1) + { + cache[n] = 1; + } + else{ + cache[n] = cache[n - 1] + cache[n - 2]; + } + cached = n; } return cache[i]; } @@ -15,7 +31,7 @@ struct Fibonacci { int main(int argc, char **argv) { // TODO: 初始化缓存结构体,使计算正确 - Fibonacci fib; + Fibonacci fib={}; ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55"); std::cout << "fibonacci(10) = " << fib.get(10) << std::endl; return 0; diff --git a/exercises/12_method_const/main b/exercises/12_method_const/main new file mode 100755 index 000000000..8095cba6d Binary files /dev/null and b/exercises/12_method_const/main differ diff --git a/exercises/12_method_const/main.cpp b/exercises/12_method_const/main.cpp index 5521be4da..d1f412d8d 100644 --- a/exercises/12_method_const/main.cpp +++ b/exercises/12_method_const/main.cpp @@ -5,7 +5,8 @@ struct Fibonacci { int numbers[11]; // TODO: 修改方法签名和实现,使测试通过 - int get(int i) { + int get(int i) const{ // const 成员函数:不修改对象,可在 const 对象上调用 + return numbers[i]; } }; diff --git a/exercises/13_class/main b/exercises/13_class/main new file mode 100755 index 000000000..bd24c4c76 Binary files /dev/null and b/exercises/13_class/main differ diff --git a/exercises/13_class/main.cpp b/exercises/13_class/main.cpp index 9afa98c5b..22c9ebe94 100644 --- a/exercises/13_class/main.cpp +++ b/exercises/13_class/main.cpp @@ -15,11 +15,28 @@ class Fibonacci { public: // TODO: 实现构造器 // Fibonacci() + Fibonacci():cache{},cached{0} {} // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if(i < cached) + { + return cache[i]; + } + for (int n = cached; n <= i;++n) + { + if(n==0) + { + cache[n] = 0; + } + else if (n==1) + { + cache[n] = 1; + } + else{ + cache[n] = cache[n - 1] + cache[n - 2]; + } + cached = n; } return cache[i]; } diff --git a/exercises/14_class_destruct/main b/exercises/14_class_destruct/main new file mode 100755 index 000000000..3a5a897d3 Binary files /dev/null and b/exercises/14_class_destruct/main differ diff --git a/exercises/14_class_destruct/main.cpp b/exercises/14_class_destruct/main.cpp index 42150e8ca..70da506f2 100644 --- a/exercises/14_class_destruct/main.cpp +++ b/exercises/14_class_destruct/main.cpp @@ -11,15 +11,34 @@ class DynFibonacci { public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity): cache(new size_t[capacity]), cached(0) {} // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() + { + delete[] cache; // 释放单个对象的内存还是对象数组的内存 + } // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if(i < cached) + { + return cache[i]; + } + for (int n = cached; n <= i;++n) + { + if(n==0) + { + cache[n] = 0; + } + else if (n==1) + { + cache[n] = 1; + } + else{ + cache[n] = cache[n - 1] + cache[n - 2]; + } + cached = n; } return cache[i]; } diff --git a/exercises/15_class_clone/main b/exercises/15_class_clone/main new file mode 100755 index 000000000..628ca8515 Binary files /dev/null and b/exercises/15_class_clone/main differ diff --git a/exercises/15_class_clone/main.cpp b/exercises/15_class_clone/main.cpp index f74b70391..14b0e35e2 100644 --- a/exercises/15_class_clone/main.cpp +++ b/exercises/15_class_clone/main.cpp @@ -7,22 +7,54 @@ class DynFibonacci { size_t *cache; int cached; + int capacity; public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity): cache(new size_t[capacity]()), cached(0) { + this->capacity = capacity; + } // TODO: 实现复制构造器 - DynFibonacci(DynFibonacci const &) = delete; + DynFibonacci(DynFibonacci const &other) //在一个类的成员函数中,可以访问其他同类对象的私有成员。 + { + cache = new size_t[other.capacity](); + cached = other.cached; + capacity = other.capacity; + for (int i = 0; i <= other.cached; ++i) + { + cache[i] = other.cache[i]; + } + } // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() + { + delete[] cache; + }; // TODO: 实现正确的缓存优化斐波那契计算 size_t get(int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if(i < cached) + { + return cache[i]; + } + for (int n = cached; n <= i;++n) + { + if(n==0) + { + cache[n] = 0; + } + else if (n==1) + { + cache[n] = 1; + } + else{ + cache[n] = cache[n - 1] + cache[n - 2]; + } + } + cached = i; return cache[i]; } @@ -42,6 +74,7 @@ int main(int argc, char **argv) { DynFibonacci fib(12); ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55"); DynFibonacci const fib_ = fib; + std::cout << fib_.get(10); ASSERT(fib_.get(10) == fib.get(10), "Object cloned"); return 0; } diff --git a/exercises/16_class_move/main b/exercises/16_class_move/main new file mode 100755 index 000000000..76052b516 Binary files /dev/null and b/exercises/16_class_move/main differ diff --git a/exercises/16_class_move/main.cpp b/exercises/16_class_move/main.cpp index 8d2c421da..39c2aca09 100644 --- a/exercises/16_class_move/main.cpp +++ b/exercises/16_class_move/main.cpp @@ -12,26 +12,78 @@ class DynFibonacci { size_t *cache; int cached; + int capacity; public: // TODO: 实现动态设置容量的构造器 - DynFibonacci(int capacity): cache(new ?), cached(?) {} + DynFibonacci(int capacity): cache(new size_t[capacity]), cached(0) { + this->capacity = capacity; + } // TODO: 实现移动构造器 - DynFibonacci(DynFibonacci &&) noexcept = delete; + DynFibonacci(DynFibonacci && other) noexcept + { // 移动构造直接传递指针 + cache = other.cache; + cached = other.cached; + capacity = other.capacity; + + other.cache = nullptr; + other.cached = 0; + other.capacity = 0; + + }; // TODO: 实现移动赋值 // NOTICE: ⚠ 注意移动到自身问题 ⚠ - DynFibonacci &operator=(DynFibonacci &&) noexcept = delete; + DynFibonacci &operator=(DynFibonacci && other) noexcept + { + // 1. 检查自赋值:this != &other, 赋值说明对象均已经初始化完毕; + if (this != &other) { // other为一个左值,因此其可以取地址; + // 2. 释放当前对象的资源 + delete[] cache; + + // 3. 从other对象"偷取"资源 + cache = other.cache; + cached = other.cached; + capacity = other.capacity; + + // 4. 将other对象置为空状态 + other.cache = nullptr; + other.cached = 0; + other.capacity = 0; + } + // 5. 返回当前对象的引用 + return *this; // 这是缺少的返回语句! + } // TODO: 实现析构器,释放缓存空间 - ~DynFibonacci(); + ~DynFibonacci() + { + delete[] cache; + } // TODO: 实现正确的缓存优化斐波那契计算 size_t operator[](int i) { - for (; false; ++cached) { - cache[cached] = cache[cached - 1] + cache[cached - 2]; + if(i < cached) + { + return cache[i]; + } + for (int n = cached; n <= i;++n) + { + if(n==0) + { + cache[n] = 0; + } + else if (n==1) + { + cache[n] = 1; + } + else{ + cache[n] = cache[n - 1] + cache[n - 2]; + } + } + cached = i; return cache[i]; } diff --git a/exercises/17_class_derive/main b/exercises/17_class_derive/main new file mode 100755 index 000000000..84f4ca1e1 Binary files /dev/null and b/exercises/17_class_derive/main differ diff --git a/exercises/17_class_derive/main.cpp b/exercises/17_class_derive/main.cpp index 819ae72fc..0c245df4f 100644 --- a/exercises/17_class_derive/main.cpp +++ b/exercises/17_class_derive/main.cpp @@ -50,9 +50,9 @@ int main(int argc, char **argv) { B b = B(3); // TODO: 补全三个类型的大小 - static_assert(sizeof(X) == ?, "There is an int in X"); - static_assert(sizeof(A) == ?, "There is an int in A"); - static_assert(sizeof(B) == ?, "B is an A with an X"); + static_assert(sizeof(X) == 4, "There is an int in X"); + static_assert(sizeof(A) == 4, "There is an int in A"); + static_assert(sizeof(B) == 8, "B is an A with an X"); i = 0; std::cout << std::endl diff --git a/exercises/18_class_virtual/main b/exercises/18_class_virtual/main new file mode 100755 index 000000000..29307efa0 Binary files /dev/null and b/exercises/18_class_virtual/main differ diff --git a/exercises/18_class_virtual/main.cpp b/exercises/18_class_virtual/main.cpp index ac6382413..1a5461310 100644 --- a/exercises/18_class_virtual/main.cpp +++ b/exercises/18_class_virtual/main.cpp @@ -21,7 +21,7 @@ struct B : public A { }; struct C : public B { // READ: final - char virtual_name() const final { + char virtual_name() const final { return 'C'; } char direct_name() const { @@ -42,38 +42,38 @@ int main(int argc, char **argv) { C c; D d; - ASSERT(a.virtual_name() == '?', MSG); - ASSERT(b.virtual_name() == '?', MSG); - ASSERT(c.virtual_name() == '?', MSG); - ASSERT(d.virtual_name() == '?', MSG); - ASSERT(a.direct_name() == '?', MSG); - ASSERT(b.direct_name() == '?', MSG); - ASSERT(c.direct_name() == '?', MSG); - ASSERT(d.direct_name() == '?', MSG); + ASSERT(a.virtual_name() == 'A', MSG); + ASSERT(b.virtual_name() == 'B', MSG); + ASSERT(c.virtual_name() == 'C', MSG); + ASSERT(d.virtual_name() == 'C', MSG); + ASSERT(a.direct_name() == 'A', MSG); + ASSERT(b.direct_name() == 'B', MSG); + ASSERT(c.direct_name() == 'C', MSG); + ASSERT(d.direct_name() == 'D', MSG); - A &rab = b; + A &rab = b; // 取决于指针的状态,非 B &rbc = c; C &rcd = d; - ASSERT(rab.virtual_name() == '?', MSG); - ASSERT(rbc.virtual_name() == '?', MSG); - ASSERT(rcd.virtual_name() == '?', MSG); - ASSERT(rab.direct_name() == '?', MSG); - ASSERT(rbc.direct_name() == '?', MSG); - ASSERT(rcd.direct_name() == '?', MSG); + ASSERT(rab.virtual_name() == 'B', MSG); + ASSERT(rbc.virtual_name() == 'C', MSG); + ASSERT(rcd.virtual_name() == 'C', MSG); + ASSERT(rab.direct_name() == 'A', MSG); + ASSERT(rbc.direct_name() == 'B', MSG); + ASSERT(rcd.direct_name() == 'C', MSG); A &rac = c; B &rbd = d; - ASSERT(rac.virtual_name() == '?', MSG); - ASSERT(rbd.virtual_name() == '?', MSG); - ASSERT(rac.direct_name() == '?', MSG); - ASSERT(rbd.direct_name() == '?', MSG); + ASSERT(rac.virtual_name() == 'C', MSG); + ASSERT(rbd.virtual_name() == 'C', MSG); + ASSERT(rac.direct_name() == 'A', MSG); + ASSERT(rbd.direct_name() == 'B', MSG); A &rad = d; - ASSERT(rad.virtual_name() == '?', MSG); - ASSERT(rad.direct_name() == '?', MSG); + ASSERT(rad.virtual_name() == 'C', MSG); + ASSERT(rad.direct_name() == 'A', MSG); return 0; } diff --git a/exercises/19_class_virtual_destruct/main b/exercises/19_class_virtual_destruct/main new file mode 100755 index 000000000..8c716888f Binary files /dev/null and b/exercises/19_class_virtual_destruct/main differ diff --git a/exercises/19_class_virtual_destruct/main.cpp b/exercises/19_class_virtual_destruct/main.cpp index cdd54f74f..d8b10803c 100644 --- a/exercises/19_class_virtual_destruct/main.cpp +++ b/exercises/19_class_virtual_destruct/main.cpp @@ -5,12 +5,12 @@ struct A { // TODO: 正确初始化静态字段 - static int num_a = 0; + static int num_a; A() { ++num_a; } - ~A() { + virtual ~A() { --num_a; } @@ -18,9 +18,11 @@ struct A { return 'A'; } }; +int A::num_a = 0; + struct B final : public A { // TODO: 正确初始化静态字段 - static int num_b = 0; + static int num_b; B() { ++num_b; @@ -33,14 +35,16 @@ struct B final : public A { return 'B'; } }; +int B::num_b = 0; int main(int argc, char **argv) { auto a = new A; - auto b = new B; - ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); - ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); - ASSERT(a->name() == '?', "Fill in the correct value for a->name()"); - ASSERT(b->name() == '?', "Fill in the correct value for b->name()"); + auto b = new B; // 创建b时会调用a + + ASSERT(A::num_a == 2, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == 1, "Fill in the correct value for B::num_b"); + ASSERT(a->name() == 'A', "Fill in the correct value for a->name()"); + ASSERT(b->name() == 'B', "Fill in the correct value for b->name()"); delete a; delete b; @@ -48,13 +52,14 @@ int main(int argc, char **argv) { ASSERT(B::num_b == 0, "Every B was destroyed"); A *ab = new B;// 派生类指针可以随意转换为基类指针 - ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a"); - ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b"); - ASSERT(ab->name() == '?', "Fill in the correct value for ab->name()"); + ASSERT(A::num_a == 1, "Fill in the correct value for A::num_a"); + ASSERT(B::num_b == 1, "Fill in the correct value for B::num_b"); + ASSERT(ab->name() == 'B', "Fill in the correct value for ab->name()"); // TODO: 基类指针无法随意转换为派生类指针,补全正确的转换语句 - B &bb = *ab; - ASSERT(bb.name() == '?', "Fill in the correct value for bb->name()"); + B &bb = dynamic_cast(*ab); + + ASSERT(bb.name() == 'B', "Fill in the correct value for bb->name()"); // TODO: ---- 以下代码不要修改,通过改正类定义解决编译问题 ---- delete ab;// 通过指针可以删除指向的对象,即使是多态对象 diff --git a/exercises/20_function_template/main b/exercises/20_function_template/main new file mode 100755 index 000000000..f668a19c9 Binary files /dev/null and b/exercises/20_function_template/main differ diff --git a/exercises/20_function_template/main.cpp b/exercises/20_function_template/main.cpp index cb6d978d3..710ff3ac7 100644 --- a/exercises/20_function_template/main.cpp +++ b/exercises/20_function_template/main.cpp @@ -2,7 +2,8 @@ // READ: 函数模板 // TODO: 将这个函数模板化 -int plus(int a, int b) { +template +T plus(T a, T b) { return a + b; } @@ -12,9 +13,9 @@ int main(int argc, char **argv) { // THINK: 浮点数何时可以判断 ==?何时必须判断差值? ASSERT(plus(1.25f, 2.5f) == 3.75f, "Plus two float"); - ASSERT(plus(1.25, 2.5) == 3.75, "Plus two double"); - // TODO: 修改判断条件使测试通过 - ASSERT(plus(0.1, 0.2) == 0.3, "How to make this pass?"); + ASSERT(plus(1.25, 2.5) == 3.75, "Plus two double"); // + // TODO: 修改判断条件使测试通过 cpp浮点数需要为2^n, 0.5,0.05 + ASSERT(std::abs(plus(0.1, 0.2) - 0.3) < 1e-10, "How to make this pass?"); return 0; } diff --git a/exercises/21_runtime_datatype/main b/exercises/21_runtime_datatype/main new file mode 100755 index 000000000..751d9d9dc Binary files /dev/null and b/exercises/21_runtime_datatype/main differ diff --git a/exercises/21_runtime_datatype/main.cpp b/exercises/21_runtime_datatype/main.cpp index 9c4bf376a..e64cb70d6 100644 --- a/exercises/21_runtime_datatype/main.cpp +++ b/exercises/21_runtime_datatype/main.cpp @@ -1,7 +1,7 @@ #include "../exercise.h" #include -enum class DataType { +enum class DataType { // int默认 Float, Double, }; @@ -11,20 +11,30 @@ enum class DataType { struct TaggedUnion { DataType type; // NOTICE: struct/union 可以相互任意嵌套。 - union { + union { // float f; double d; }; }; // TODO: 将这个函数模板化用于 sigmoid_dyn -float sigmoid(float x) { +template +T sigmoid(T x) { return 1 / (1 + std::exp(-x)); } TaggedUnion sigmoid_dyn(TaggedUnion x) { TaggedUnion ans{x.type}; // TODO: 根据 type 调用 sigmoid + if(x.type == DataType::Float) + { + ans.f = sigmoid(x.f); + } + else if (x.type == DataType::Double) + { + ans.d = sigmoid(x.d); + } + return ans; } @@ -41,5 +51,6 @@ int main(int argc, char **argv) { auto yd = sigmoid_dyn(xd); ASSERT(yd.type == DataType::Double, "type mismatch"); ASSERT(yd.d == 1 / (1 + std::exp(-5.0)), "sigmoid double"); + std::cout << sizeof(DataType) << std::endl; return 0; } diff --git a/exercises/22_class_template/main b/exercises/22_class_template/main new file mode 100755 index 000000000..a1eb8c29c Binary files /dev/null and b/exercises/22_class_template/main differ diff --git a/exercises/22_class_template/main.cpp b/exercises/22_class_template/main.cpp index d4985d904..d7e3e7d45 100644 --- a/exercises/22_class_template/main.cpp +++ b/exercises/22_class_template/main.cpp @@ -4,12 +4,17 @@ template struct Tensor4D { - unsigned int shape[4]; + unsigned int shape[4]; // 存储四个维度信息 T *data; - Tensor4D(unsigned int const shape_[4], T const *data_) { + Tensor4D(unsigned int *shape_, T const *data_) { unsigned int size = 1; // TODO: 填入正确的 shape 并计算 size + for (int i = 0; i < 4; ++i) + { + shape[i] = shape_[i]; + size *= shape_[i]; // 总的元素数量 + } data = new T[size]; std::memcpy(data, data_, size * sizeof(T)); } @@ -28,6 +33,52 @@ struct Tensor4D { // 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。 Tensor4D &operator+=(Tensor4D const &others) { // TODO: 实现单向广播的加法 + // 形状不同的长度必须为1 + // 1.检查维度 + int i,idx = 1,thissize = 1,othersize = 1; // 第i个维度存在元素 + int flag_dim = -1,beforesize = 1; + for (i = 0; i < 4; ++i) { + if(flag_dim == -1 && shape[i] != others.shape[i]) + { + flag_dim = i; // 设置不同维度时的维度坐标 + } + if(flag_dim == -1) + { + beforesize *= shape[i]; // 记录this的元素个数 + } + thissize *= this->shape[i]; + othersize *= others.shape[i]; // 计算起始位置以及终止位置 + } + // 一、不进行广播 + if (flag_dim == -1) { + for (int i = 0; i < thissize; ++i) { + data[i] += others.data[i]; + } + return *this; + } + std::cout << "thissize:" << thissize << std::endl; + std::cout << "othersize:" << othersize << std::endl; + std::cout << "idx:" << idx << std::endl; + + // 将4维shape 2维化 + int step = 1,other_step = 1 ; + std::cout << "flag_dim" << flag_dim << std::endl; + for (int i = 3; i >= flag_dim; --i) { + step *= shape[i]; + other_step *= others.shape[i]; + } + //std::cout << "step:" << other_step << std::endl; + + // 二、k 为batch,必须保证batch的维度相同 + for (int k = 0; k < beforesize; ++k) { + for (int i = 0; i < step; ++i)// this:[2,3,4]. -> [2,1,12] other:[2,1,4] + { + + this->data[i + k * step] += others.data[(i + k * step) % other_step + k * other_step];// 1 -> 12 : 1 -> 4. + //std::cout << "this_idx: " << i + k * step << std::endl; + //std::cout << "other_idx: " << ((i + k * step) % other_step + k * other_step) % othersize << std::endl; + } + } return *this; } }; @@ -35,7 +86,7 @@ struct Tensor4D { // ---- 不要修改以下代码 ---- int main(int argc, char **argv) { { - unsigned int shape[]{1, 2, 3, 4}; + unsigned int shape[]{1, 2, 3, 4}; // clang-format off int data[]{ 1, 2, 3, 4, @@ -45,8 +96,10 @@ int main(int argc, char **argv) { 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; + // clang-format on auto t0 = Tensor4D(shape, data); + auto t1 = Tensor4D(shape, data); t0 += t1; for (auto i = 0u; i < sizeof(data) / sizeof(*data); ++i) { @@ -105,5 +158,6 @@ int main(int argc, char **argv) { for (auto i = 0u; i < sizeof(d0) / sizeof(*d0); ++i) { ASSERT(t0.data[i] == d0[i] + 1, "Every element of t0 should be incremented by 1 after adding t1 to it."); } + } } diff --git a/exercises/23_template_const/main b/exercises/23_template_const/main new file mode 100755 index 000000000..d95f92f41 Binary files /dev/null and b/exercises/23_template_const/main differ diff --git a/exercises/23_template_const/main.cpp b/exercises/23_template_const/main.cpp index e0105e168..d8380ebe3 100644 --- a/exercises/23_template_const/main.cpp +++ b/exercises/23_template_const/main.cpp @@ -8,12 +8,18 @@ struct Tensor { unsigned int shape[N]; T *data; - Tensor(unsigned int const shape_[N]) { + Tensor(unsigned int const shape_[N]){ unsigned int size = 1; // TODO: 填入正确的 shape 并计算 size - data = new T[size]; + for (int i = 0; i < N;++i) + { + shape[i] = shape_[i]; + size *= shape_[i]; + } + data = new T[size]; std::memset(data, 0, size * sizeof(T)); } + ~Tensor() { delete[] data; } @@ -35,7 +41,23 @@ struct Tensor { for (unsigned int i = 0; i < N; ++i) { ASSERT(indices[i] < shape[i], "Invalid index"); // TODO: 计算 index + if(i == N-1) + { + index += indices[i]; + } + else{ + int j = i + 1,temp = 1; + while (j < N) // 子tensor计算 + { + temp *= shape[j]; + j++; + } + index += indices[i] * temp; + } + } + std::cout << index << std::endl; + return index; } }; @@ -43,10 +65,10 @@ struct Tensor { // ---- 不要修改以下代码 ---- int main(int argc, char **argv) { { - unsigned int shape[]{2, 3, 4, 5}; + unsigned int shape[]{2, 3, 4, 5}; // 四维张量的shape [batch,channel,H,W] auto tensor = Tensor<4, int>(shape); - unsigned int i0[]{0, 0, 0, 0}; + unsigned int i0[]{0, 0, 0, 0}; // 四维张量的索引 tensor[i0] = 1; ASSERT(tensor[i0] == 1, "tensor[i0] should be 1"); ASSERT(tensor.data[0] == 1, "tensor[i0] should be 1"); diff --git a/exercises/24_std_array/main b/exercises/24_std_array/main new file mode 100755 index 000000000..d8e6e4e2d Binary files /dev/null and b/exercises/24_std_array/main differ diff --git a/exercises/24_std_array/main.cpp b/exercises/24_std_array/main.cpp index c29718d9d..1c99d7f5e 100644 --- a/exercises/24_std_array/main.cpp +++ b/exercises/24_std_array/main.cpp @@ -8,21 +8,21 @@ int main(int argc, char **argv) { { std::array arr{{1, 2, 3, 4, 5}}; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); + ASSERT(arr.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(arr) == 20, "Fill in the correct value."); int ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(arr.?, ans, ?) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(arr.data(), ans, 20) == 0, "Fill in the correct values."); } { std::array arr; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); + ASSERT(arr.size() == 8, "Fill in the correct value."); + ASSERT(sizeof(arr) == 64, "Fill in the correct value."); } { std::array arr{"Hello, InfiniTensor!"}; - ASSERT(arr.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(arr) == ?, "Fill in the correct value."); - ASSERT(std::strcmp(arr.?, "Hello, InfiniTensor!") == 0, "Fill in the correct value."); + ASSERT(arr.size() == 21, "Fill in the correct value."); + ASSERT(sizeof(arr) == 21, "Fill in the correct value."); + ASSERT(std::strcmp(arr.data(), "Hello, InfiniTensor!") == 0, "Fill in the correct value."); } return 0; } diff --git a/exercises/25_std_vector/main b/exercises/25_std_vector/main new file mode 100755 index 000000000..ced3e8697 Binary files /dev/null and b/exercises/25_std_vector/main differ diff --git a/exercises/25_std_vector/main.cpp b/exercises/25_std_vector/main.cpp index f9e41bb78..e5f5c223a 100644 --- a/exercises/25_std_vector/main.cpp +++ b/exercises/25_std_vector/main.cpp @@ -8,81 +8,81 @@ int main(int argc, char **argv) { { std::vector vec{1, 2, 3, 4, 5}; - ASSERT(vec.size() == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); // THINK: `std::vector` 的大小是什么意思?与什么有关? - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); // 3个指针,起始指针,下一个元素指针,终止指针 3*8,固定为12/24 int ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(vec.?, ans, sizeof(ans)) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(vec.data(), ans, sizeof(ans)) == 0, "Fill in the correct values."); } { std::vector vec{1, 2, 3, 4, 5}; { - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); double ans[]{1, 2, 3, 4, 5}; - ASSERT(std::memcmp(vec.?, ans, sizeof(ans)) == 0, "Fill in the correct values."); + ASSERT(std::memcmp(vec.data(), ans, sizeof(ans)) == 0, "Fill in the correct values."); } { vec.push_back(6); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 6, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); vec.pop_back(); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(vec.size() == 5, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); } { vec[4] = 6; - ASSERT(vec[0] == ?, "Fill in the correct value."); - ASSERT(vec[1] == ?, "Fill in the correct value."); - ASSERT(vec[2] == ?, "Fill in the correct value."); - ASSERT(vec[3] == ?, "Fill in the correct value."); - ASSERT(vec[4] == ?, "Fill in the correct value."); + ASSERT(vec[0] == 1, "Fill in the correct value."); + ASSERT(vec[1] == 2, "Fill in the correct value."); + ASSERT(vec[2] == 3, "Fill in the correct value."); + ASSERT(vec[3] == 4, "Fill in the correct value."); + ASSERT(vec[4] == 6, "Fill in the correct value."); } { - // THINK: `std::vector` 插入删除的时间复杂度是什么? - vec.insert(?, 1.5); + // THINK: `std::vector` 插入删除的时间复杂度是什么? o(n) + vec.insert(vec.begin()+1, 1.5); ASSERT((vec == std::vector{1, 1.5, 2, 3, 4, 6}), "Make this assertion pass."); - vec.erase(?); + vec.erase(vec.begin()+3); ASSERT((vec == std::vector{1, 1.5, 2, 4, 6}), "Make this assertion pass."); } { - vec.shrink_to_fit(); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + vec.shrink_to_fit(); // 减小容量以适应size + ASSERT(vec.capacity() == 5, "Fill in the correct value."); vec.clear(); ASSERT(vec.empty(), "`vec` is empty now."); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + ASSERT(vec.size() == 0, "Fill in the correct value."); + ASSERT(vec.capacity() == 5, "Fill in the correct value."); } } { - std::vector vec(?, ?); // TODO: 调用正确的构造函数 + std::vector vec(48,'z'); // TODO: 调用正确的构造函数 ASSERT(vec[0] == 'z', "Make this assertion pass."); ASSERT(vec[47] == 'z', "Make this assertion pass."); ASSERT(vec.size() == 48, "Make this assertion pass."); - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); { auto capacity = vec.capacity(); vec.resize(16); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in a correct identifier."); + ASSERT(vec.size() == 16, "Fill in the correct value."); + ASSERT(vec.capacity() == 48, "Fill in a correct identifier."); } { - vec.reserve(256); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); + vec.reserve(256); // 预留空间 + ASSERT(vec.size() == 16, "Fill in the correct value."); + ASSERT(vec.capacity() == 256, "Fill in the correct value."); } { vec.push_back('a'); vec.push_back('b'); vec.push_back('c'); vec.push_back('d'); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(vec.capacity() == ?, "Fill in the correct value."); - ASSERT(vec[15] == ?, "Fill in the correct value."); - ASSERT(vec[?] == 'a', "Fill in the correct value."); - ASSERT(vec[?] == 'b', "Fill in the correct value."); - ASSERT(vec[?] == 'c', "Fill in the correct value."); - ASSERT(vec[?] == 'd', "Fill in the correct value."); + ASSERT(vec.size() == 20, "Fill in the correct value."); + ASSERT(vec.capacity() == 256, "Fill in the correct value."); + ASSERT(vec[15] == 'z', "Fill in the correct value."); + ASSERT(vec[16] == 'a', "Fill in the correct value."); + ASSERT(vec[17] == 'b', "Fill in the correct value."); + ASSERT(vec[18] == 'c', "Fill in the correct value."); + ASSERT(vec[19] == 'd', "Fill in the correct value."); } } diff --git a/exercises/26_std_vector_bool/main b/exercises/26_std_vector_bool/main new file mode 100755 index 000000000..cdf684cc4 Binary files /dev/null and b/exercises/26_std_vector_bool/main differ diff --git a/exercises/26_std_vector_bool/main.cpp b/exercises/26_std_vector_bool/main.cpp index b4ab4f9c4..e24f0edcd 100644 --- a/exercises/26_std_vector_bool/main.cpp +++ b/exercises/26_std_vector_bool/main.cpp @@ -6,29 +6,29 @@ // TODO: 将下列 `?` 替换为正确的代码 int main(int argc, char **argv) { - std::vector vec(?, ?);// TODO: 正确调用构造函数 + std::vector vec(100, true);// TODO: 正确调用构造函数 ASSERT(vec[0], "Make this assertion pass."); ASSERT(vec[99], "Make this assertion pass."); ASSERT(vec.size() == 100, "Make this assertion pass."); // NOTICE: 平台相关!注意 CI:Ubuntu 上的值。 std::cout << "sizeof(std::vector) = " << sizeof(std::vector) << std::endl; - ASSERT(sizeof(vec) == ?, "Fill in the correct value."); + ASSERT(sizeof(vec) == 24, "Fill in the correct value."); { vec[20] = false; - ASSERT(?vec[20], "Fill in `vec[20]` or `!vec[20]`."); + ASSERT(!vec[20], "Fill in `vec[20]` or `!vec[20]`."); } { vec.push_back(false); - ASSERT(vec.size() == ?, "Fill in the correct value."); - ASSERT(?vec[100], "Fill in `vec[100]` or `!vec[100]`."); + ASSERT(vec.size() == 101, "Fill in the correct value."); + ASSERT(!vec[100], "Fill in `vec[100]` or `!vec[100]`."); } { - auto ref = vec[30]; - ASSERT(?ref, "Fill in `ref` or `!ref`"); + auto ref = vec[30]; // 普通类型为值拷贝,特殊类型bool为引用传递 + ASSERT(ref, "Fill in `ref` or `!ref`"); ref = false; - ASSERT(?ref, "Fill in `ref` or `!ref`"); + ASSERT(!ref, "Fill in `ref` or `!ref`"); // THINK: WHAT and WHY? - ASSERT(?vec[30], "Fill in `vec[30]` or `!vec[30]`."); + ASSERT(!vec[30], "Fill in `vec[30]` or `!vec[30]`."); } return 0; } diff --git a/exercises/27_strides/main b/exercises/27_strides/main new file mode 100755 index 000000000..a86536fbc Binary files /dev/null and b/exercises/27_strides/main differ diff --git a/exercises/27_strides/main.cpp b/exercises/27_strides/main.cpp index baceaf2a9..9540bec90 100644 --- a/exercises/27_strides/main.cpp +++ b/exercises/27_strides/main.cpp @@ -18,7 +18,22 @@ std::vector strides(std::vector const &shape) { // TODO: 完成函数体,根据张量形状计算张量连续存储时的步长。 // READ: 逆向迭代器 std::vector::rbegin // 使用逆向迭代器可能可以简化代码 - return strides; + for (int i = 0; i < shape.size();++i) + { + if(i == shape.size() - 1) + { + strides[i] = 1; + } + else{ + int temp = 1; + for (int j = i + 1; j < shape.size(); ++j) { + temp *= shape[j]; + } + strides[i] = temp; + } + //std::cout << strides[i] << " "; + } + return strides; } // ---- 不要修改以下代码 ---- diff --git a/exercises/28_std_string/main b/exercises/28_std_string/main new file mode 100755 index 000000000..9db50933e Binary files /dev/null and b/exercises/28_std_string/main differ diff --git a/exercises/28_std_string/main.cpp b/exercises/28_std_string/main.cpp index d8b276274..0dd67934b 100644 --- a/exercises/28_std_string/main.cpp +++ b/exercises/28_std_string/main.cpp @@ -6,13 +6,15 @@ int main(int argc, char **argv) { // READ: 字符串字面量 using namespace std::string_literals; - auto hello = "Hello"s; - auto world = "world"; + auto hello = "Hello"s; // std:;string + auto world = "world"; // const char * + const char *p = "i love lx"; + // READ: `decltype` 表达式 // READ: `std::is_same_v` 元编程判别 - ASSERT((std::is_same_v), "Fill in the missing type."); - ASSERT((std::is_same_v), "Fill in the missing type."); + ASSERT((std::is_same_v), "Fill in the missing type."); + ASSERT((std::is_same_v), "Fill in the missing type."); // TODO: 将 `?` 替换为正确的字符串 - ASSERT(hello + ", " + world + '!' == "?", "Fill in the missing string."); + ASSERT(hello + ", " + world + '!' == "Hello, world!", "Fill in the missing string."); return 0; } diff --git a/exercises/29_std_map/main b/exercises/29_std_map/main new file mode 100755 index 000000000..4a70ccf33 Binary files /dev/null and b/exercises/29_std_map/main differ diff --git a/exercises/29_std_map/main.cpp b/exercises/29_std_map/main.cpp index fcccca347..21fc16ffb 100644 --- a/exercises/29_std_map/main.cpp +++ b/exercises/29_std_map/main.cpp @@ -7,11 +7,19 @@ template bool key_exists(std::map const &map, k const &key) { // TODO: 实现函数 + for (auto it = map.begin(); it != map.end();++it) + { + if (it -> first == key) { + return true; + } + } + return false; } template void set(std::map &map, k key, v value) { // TODO: 实现函数 + map[key] = value; } // ---- 不要修改以下代码 ---- diff --git a/exercises/30_std_unique_ptr/main b/exercises/30_std_unique_ptr/main new file mode 100755 index 000000000..008d17f02 Binary files /dev/null and b/exercises/30_std_unique_ptr/main differ diff --git a/exercises/30_std_unique_ptr/main.cpp b/exercises/30_std_unique_ptr/main.cpp index 9b98b5794..325255128 100644 --- a/exercises/30_std_unique_ptr/main.cpp +++ b/exercises/30_std_unique_ptr/main.cpp @@ -21,30 +21,30 @@ class Resource { } }; -using Unique = std::unique_ptr; +using Unique = std::unique_ptr; // 类Resource的unique指针; Unique reset(Unique ptr) { - if (ptr) ptr->record('r'); - return std::make_unique(); + if (ptr) ptr->record('r'); // 如果指针存在,则存储字符'r' + return std::make_unique(); // 返回新指针 当 unique_ptr 变为 nullptr 时(无论是通过赋值、reset() 还是函数返回),如果它原来持有对象,那么这个对象会立即被析构。 } Unique drop(Unique ptr) { - if (ptr) ptr->record('d'); + if (ptr) ptr->record('d'); // 返回空指针,作用域结束 return nullptr; } Unique forward(Unique ptr) { - if (ptr) ptr->record('f'); + if (ptr) ptr->record('f'); // 返回当前指针 return ptr; } int main(int argc, char **argv) { std::vector problems[3]; - drop(forward(reset(nullptr))); - problems[0] = std::move(RECORDS); + drop(forward(reset(nullptr))); // Unique -> fd + problems[0] = std::move(RECORDS); - forward(drop(reset(forward(forward(reset(nullptr)))))); + forward(drop(reset(forward(forward(reset(nullptr)))))); // ffr d problems[1] = std::move(RECORDS); - drop(drop(reset(drop(reset(reset(nullptr)))))); + drop(drop(reset(drop(reset(reset(nullptr)))))); // r d d problems[2] = std::move(RECORDS); // ---- 不要修改以上代码 ---- @@ -53,8 +53,8 @@ int main(int argc, char **argv) { {"fd"}, // TODO: 分析 problems[1] 中资源的生命周期,将记录填入 `std::vector` // NOTICE: 此题结果依赖对象析构逻辑,平台相关,提交时以 CI 实际运行平台为准 - {"", "", "", "", "", "", "", ""}, - {"", "", "", "", "", "", "", ""}, + {"d", "ffr"}, + {"d", "d", "r"}, }; // ---- 不要修改以下代码 ---- diff --git a/exercises/31_std_shared_ptr/main b/exercises/31_std_shared_ptr/main new file mode 100755 index 000000000..edd35a184 Binary files /dev/null and b/exercises/31_std_shared_ptr/main differ diff --git a/exercises/31_std_shared_ptr/main.cpp b/exercises/31_std_shared_ptr/main.cpp index febbbcc6f..3c39ebf76 100644 --- a/exercises/31_std_shared_ptr/main.cpp +++ b/exercises/31_std_shared_ptr/main.cpp @@ -7,39 +7,39 @@ // TODO: 将下列 `?` 替换为正确的值 int main(int argc, char **argv) { auto shared = std::make_shared(10); - std::shared_ptr ptrs[]{shared, shared, shared}; + std::shared_ptr ptrs[]{shared, shared, shared}; // 共享指针shared_ptr - std::weak_ptr observer = shared; - ASSERT(observer.use_count() == ?, ""); + std::weak_ptr observer = shared; // weak_ptr "当前指向同一对象的 shared_ptr 的数量" + ASSERT(observer.use_count() == 4, ""); - ptrs[0].reset(); - ASSERT(observer.use_count() == ?, ""); + ptrs[0].reset(); // 变成nullptr并且清楚引用计数 + ASSERT(observer.use_count() == 3, ""); ptrs[1] = nullptr; - ASSERT(observer.use_count() == ?, ""); + ASSERT(observer.use_count() == 2, ""); - ptrs[2] = std::make_shared(*shared); - ASSERT(observer.use_count() == ?, ""); + ptrs[2] = std::make_shared(*shared); // 创建一个新的副本,原对象的旧值被销毁 + ASSERT(observer.use_count() == 1, ""); ptrs[0] = shared; ptrs[1] = shared; - ptrs[2] = std::move(shared); - ASSERT(observer.use_count() == ?, ""); + ptrs[2] = std::move(shared); // 移动语义 + ASSERT(observer.use_count() == 3, ""); - std::ignore = std::move(ptrs[0]); + std::ignore = std::move(ptrs[0]); // 2 ptrs[1] = std::move(ptrs[1]); - ptrs[1] = std::move(ptrs[2]); - ASSERT(observer.use_count() == ?, ""); + ptrs[1] = std::move(ptrs[2]); + ASSERT(observer.use_count() == 2, ""); - shared = observer.lock(); - ASSERT(observer.use_count() == ?, ""); + shared = observer.lock(); // weak_ptr获取得到shared_ptr,引用计数 + 1 + ASSERT(observer.use_count() == 3, ""); shared = nullptr; for (auto &ptr : ptrs) ptr = nullptr; - ASSERT(observer.use_count() == ?, ""); + ASSERT(observer.use_count() == 0, ""); - shared = observer.lock(); - ASSERT(observer.use_count() == ?, ""); + shared = observer.lock(); // 得到其对应的shared_ptr + ASSERT(observer.use_count() == 0, ""); return 0; } diff --git a/exercises/32_std_transform/main b/exercises/32_std_transform/main new file mode 100755 index 000000000..d00dfc0d3 Binary files /dev/null and b/exercises/32_std_transform/main differ diff --git a/exercises/32_std_transform/main.cpp b/exercises/32_std_transform/main.cpp index f4dc25a5c..92d16b228 100644 --- a/exercises/32_std_transform/main.cpp +++ b/exercises/32_std_transform/main.cpp @@ -9,6 +9,14 @@ int main(int argc, char **argv) { std::vector val{8, 13, 21, 34, 55}; // TODO: 调用 `std::transform`,将 `v` 中的每个元素乘以 2,并转换为字符串,存入 `ans` + std::vector ans(val.size()); + std::transform(val.begin(), val.end(), ans.begin(),[](int x){ + x *= 2; + std::string str = std::to_string(x); + return str; + } + ); + // std::vector ans ASSERT(ans.size() == val.size(), "ans size should be equal to val size"); ASSERT(ans[0] == "16", "ans[0] should be 16"); diff --git a/exercises/33_std_accumulate/main b/exercises/33_std_accumulate/main new file mode 100755 index 000000000..fe36141f7 Binary files /dev/null and b/exercises/33_std_accumulate/main differ diff --git a/exercises/33_std_accumulate/main.cpp b/exercises/33_std_accumulate/main.cpp index 6326929d5..b3bef21f5 100644 --- a/exercises/33_std_accumulate/main.cpp +++ b/exercises/33_std_accumulate/main.cpp @@ -11,7 +11,8 @@ int main(int argc, char **argv) { // - 形状为 shape; // - 连续存储; // 的张量占用的字节数 - // int size = + int size = std::accumulate(shape, shape + 4, 1, + std::multiplies()) * sizeof(DataType) ; ASSERT(size == 602112, "4x1x3x224x224 = 602112"); return 0; }