# learning_cpp **Repository Path**: zyt77tz/learning_cpp ## Basic Information - **Project Name**: learning_cpp - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-12-12 - **Last Updated**: 2022-01-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # learning_cpp 学习C++的记录 22.01.15六 第八讲 STL、位运算与常用库函数 1.#include vector **vector** vector是变长数组,支持随机访问,不支持在任意O(1)插入。为了保证效率,元素的增减一般放在末尾进行。 `#include ` //头文件 `vectora;` //相当于一个动态变化的int数组 `vectorb[233]` //相当于第一维长233,第二维长度是动态变化的interesting数组 `struct rec{···}` `vectorc;` //自定义的结构体类型也可以保存在vector中 **size/empty** size函数返回vector的实际长度(包括的元素个数),empty函数返回一个bool类型,表明vector是否为空,二者复杂度都是O(1)。 **clear** clear函数把vector清空 **迭代器** 迭代器就像STL容器的“指针”,可以用星号“*”操作符解除引用 一个保存int的vector的迭代器声明方法为: `vector::interator it; `vector`的迭代器是“随机访问迭代器”,可以把`vector`的迭代器与一个整数相加减,其行为和指针的移动类似。 可以把`vector`的两个迭代器相减,其结果也和指针相类似,得到的两个迭代器对应下标之间的距离。 **begin/end** `begin`函数是返回指向`vector`中的第一个元素的迭代器。例如:`a`是一个非空的`vector`,则`a.begin()`与`a[0]`的作用相同 所有的容器都可以视作一个前闭后开的结构,`end`函数返回`vector`的尾部,第`n`个元素再往后的“边界”。`a.end()`与`a[n]`都是越界访问,其中`n = a.size()`. 下面两份代码都遍历了`vectora`,并输出它的所有元素。 ```C++ for (int i = 0; i < a.size(); i++){ cout << a[i] << endl; } for (vector::iterator it = a.agin(); it != a.end(); it++) { cout << *it << endl; } ``` **front/back** `front` 函数返回 `vector` 的第一个元素,等价于`a.begin() `和 `a[0]` `back` 函数返回 `vector` 的最后一个元素,等价于`--a.end()`和`a[a.size() - 1]` **push_back() 和 pop_back()** `a.push_back(x)` 把元素x插入到`vector a` 的尾部 `b.pop_back()` 删除 `vector a` 最后的一个元素 2. #include 头文件`queue`主要包括循环队列`queue`和优先队列`priority_queue`两个容器 声明: ```C++ queue q; struct rec{...}; queue q; //结构体rec中必须定义小于号 priority_queue q; //大根堆 priority_queue, greater q; //小根堆 priority_queue>q; ``` **循环队列 queue** ```C++ push // 从队尾插入 pop // 从对头弹出 front // 返回队头元素 back // 返回队尾元素 ``` **优先队列 priority_queue** ```C++ push // 把元素插入堆 pop // 删除堆顶元素 top // 查询堆顶元素最大值 ``` 3. #include 头文件`stack`包含栈。声明和前面的容器类似。 ```C++ push // 向栈顶插入 pop // 弹出栈顶元素 ``` 4. #include 双端队列`deque`是一个支持在两端高效插入或删除元素的连续线性储存空间。它就像是`vector` 和`queue`的结合。与`vector`相比,`deque`在头部增删元素仅需要O(1)的时间;与`queue`相比,`deque`像数组一样支持随机访问。 ```C++ [] // 随机访问 begin/end // 返回deque的头/尾迭代器 front/back // 队头队尾元素 push_back // 从队尾入队 push_front // 从对头入队 pop_back // 从对尾出队 pop_front // 从队头入队 clear // 清空队列 ``` 5. #include 头文件`set`主要包括`set`和`multiset`两个容器,分别是“有序集合”和“有序多重集合”,即前者的元素不能重复,而后者可以包含若干个相等的元素。`set`和`multiset`的内部实现是一棵红黑树,它们支持的函数基本相同。 22.01.13四 第七讲 习题 **斐波那契而数列** ```C++ class Solution { public: int Fibonacci(int n) { if (n <= 1) { return n; } return Fibonacci(n - 1) + Fibonacci(n - 2); } }; ``` **替换空格** ```C++ #include using namespace std; class Solution { public: string replaceSpaces(string &str) { string res; for (auto c : str) { if (c == ' ') { res += "%20"; } else { res += c; } } return res; } }; ``` **1+2+···+n** ```C++ class Solution { public: int getSum(int n) { int res = n; n > 0 && (res += getSum(n - 1)); return res; } }; ``` **在o(1)时间删除链表结点** ```C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void deleteNode(ListNode* node) { node->val = node->next->val; node->next = node->next->next; } }; ``` **合并两个排序的列表** ```C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* merge(ListNode* l1, ListNode* l2) { auto dummy = new ListNode(-1), tail = dummy; while (l1 && l2) if (l1->val < l2->val) { tail = tail->next = l1; l1 = l1->next; } else { tail = tail->next = l2; l2 = l2->next; } if (l1) tail->next = l1; if (l2) tail->next = l2; return dummy->next; } }; ``` **左旋字符串** ```C++ class Solution { public: string leftRotateString(string str, int n) { return str.substr(n) + str.substr(0, n); } }; ``` **字符串转化成整数** ```C++ class Solution { public: int strToInt(string str) { int k = 0; while (k < str.size() && str[k] == ' ') { k++; } long long res = 0; int minus = 1; if (k < str.size()) { if (str[k] == '-') { minus = -1, k++; } else if (str[k] == '+') { k++; } } while (k < str.size() && str[k] >= '0' && str[k] <= '9') { res = res * 10 + str[k] - '0'; if (res > 1e11) { break; } k++; } res *= minus; if (res > INT_MAX) { res = INT_MAX; } if (res < INT_MIN) { res = INT_MIN; } return res; } }; ``` **反转列表** ```C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { if (!head || !head->next) { return head; } auto p = head, q = p->next; while (q) { auto o = q->next; q->next = p; p = q, q = o; } head->next = NULL; return p; } }; ``` **两个链表的第一个公共节点** ```C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *findFirstCommonNode(ListNode *headA, ListNode *headB) { auto p = headA, q = headB; while (p != q) { if (p) { p = p->next; } else { p = headB; } if (q) { q = q->next; } else { q = headA; } } return p; } }; ``` **删除表中重复节点** ```C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* deleteDuplication(ListNode* head) { auto dummy = new ListNode(-1); dummy->next = head; auto p = dummy; while (p->next) { auto q = p->next; while (q->next && q->next->val == p->next->val) { q = q->next; } if (q == p->next) { p = q; } else { p->next = q->next; } } return dummy->next; } }; ``` 第七讲 类、结构体、指针、引用 2. 指针和引用 指针指向存放变量的值的地址。因此我们可以通过指针来修改变量的值。 **程序在操作系统中运行的一些基本概念** 进程:process(所有程序都有一个进程) 这里还有 `栈` 和 `堆` 的概念(开到栈里面的数值是不确定的) 例1: ```C++ #include using namespace std; int main() { char c = 'a'; cout << (void*)&c << endl; return 0; } ``` 例2: ```C++ #include using namespace std; char a, b; int main() { int a = 10; int* p = &a; //p本身的值就是A的地址 cout << *p << endl; //*p表示p的值 *p = a; //表示p的值 cout << p << endl; cout << a << endl; return 0; } ``` **数组可以是一种特殊的指针,指针可以做运算** ```C++ #include using namespace std; int main() { int a[5] = {1, 2, 3, 4, 5}; // char c for (int i = 0; i < 5; i++) { cout << *(a + i) << endl; } return 0; } ``` 3. 链表 ```C++ #include using namespace std; struct Node { int val; Node* nsxt; Node(int_val) : val(_val), next(NULL){} }; int main() { Node* p = new Node(1); p->next = p; //->表示:如果调用一个结构、类中成员变量,如果是指针用“->”来调用 auto q = new Node(2); //auto等价于Node* p->next = q; } ``` **如何遍历** ```C++ Node* head = p; for (Node* i = head; i; i = i->next) { cout << i->val << endl; } ``` **链表中添加一个节点** ```C++ Node* U = new Node(4); U->next = headl head = U; ``` **删除节点** 链表的删除是指:在遍历时候,遍历不到这个点 `head->next = head->next->next;` 22.01.11二 第七讲 类、结构体、指针、引用 1. 类与结构体 **类的定义** 类中的变量和函数被统一称为类的成员变量 private后面的内容是私有成员变量,在类的外部不能访问:public后面的内容是公有成员变量,在类的外部可以访问 ```C++ #include using namespace std; class person { private: int age, height; double money; string books[100]; public:{ string name; void say() { cout << "I'm" << name << endl; } int get_age() { return age; } void add_money(double x) { money += x; } } }; ``` **类的使用** ```C++ int main() { person c; c.name = "Yxc"; //c.age = 180 //错误 cout << get_age() << endl; c.add_money(100000); } ``` 结构体和类的作用是一样的,不同点在于类默认是private,结构体默认是public 22.01.10一 第六讲 函数(习题) **n的阶乘** ```C++ #include using namespace std; int fact(int n) { int res = 1; for (int i = 1; i <= n; i++) { res *= i; } return res; } int main() { int n; cin >> n; cout << fact(n) << endl; return 0; } ``` **x和y的最大值** ```C++ #include using namespace std; int max(int x, int y) { if (x > y) { return x; } return y; } int main() { int x, y; cin >> x >> y; cout << max(x, y) << endl; return 0; } ``` **最大公约数** ```C++ #include using namespace std; int gcd(int a, int b) { for (int i = 1000; i; i--) { if (a % i == 0 && b % i == 0) { return i; } } } int main() { int a, b; cin >> a >> b; cout << gcd(a, b) << endl; return 0; } ``` **交换数值** ```C++ #include using namespace std; const int N = 1010; void print(int a[], int size) { for (int i = 0; i < size; i++) { cout << a[i] << ' '; } cout << endl; } int main() { int n, size; int a[N]; cin >> n >> size; for (int i = 0; i < n; i++) { cin >> a[i]; } print(a, size); return 0; } ``` **打印数字** ```C++ #include using namespace std; const int N = 1010; void print(int a[], int size) { for (int i = 0; i < size; i++) { cout << a[i] << ' '; } cout << endl; } int main() { int n, size; int a[N]; cin >> n >> size; for (int i = 0; i < n; i++) { cin >> a[i]; } print(a, size); return 0; } ``` **打印矩阵** ```C++ #include using namespace std; void print2D(int a[][100], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { cout << a[i][j] << ' '; } cout << endl; } } int main() { int a[100][100]; int row, col; cin >> row >> col; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { cin >> a[i][j]; } } print2D(a, row, col); return 0; } ``` **递归求阶乘** ```C++ #include using namespace std; int fact(int n) { if (n <= 1) { return 1; } return n * fact(n - 1); } int main() { int n; cin >> n; cout << fact(n) << endl; return 0; } ``` **递归求斐波那契而数列** ```C++ #include using namespace std; int fbq(int n) { if (n == 1 || n == 2) { return 1; } return fbq(n - 1) + fbq(n - 2); } int main() { int n; cin >> n; cout << fbq(n); return 0; } ``` **绝对值** ```C++ #include using namespace std; int abs(int x) { if (x >= 0) { return x; } else { return -x; } } int main() { int x; cin >> x; cout << abs(x) << endl; return 0; } ``` **两个数的和** ```C++ #include #include using namespace std; double add(double x, double y) { if (x >= -1000 && y <= 1000) { return x + y; } } int main() { double x, y; cin >> x >> y; printf("%.2lf", add(x, y)); return 0; } ``` **区间求和** ```C++ #include using namespace std; int sum(int l, int r) { int sum = 0; for (int i = l; i <= r; i++) { sum +=i; } return sum; } int main() { int l, r; cin >> l >> r; cout << sum(l, r) << endl; return 0; } ``` **最小公倍数** ```C++ #include using namespace std; int lcm(int a, int b) { for (int i = 1; i <= a * b; i++) { if (i % a == 0 && i % b == 0) { return i; } } return -1; } int main() { int a, b; cin >> a >> b; cout << lcm(a, b) << endl; return 0; } ``` **复制数组** ```C++ #include using namespace std; const int N = 110; void copy(int a[], int b[], int size) { for (int i = 0; i < size; i++) { b[i] = a[i]; } } int main() { int a[N], b[N]; int n, m, size; cin >> n >> m >> size; for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < m; i++) { cin >> b[i]; } copy(a, b, size); for (int i = 0; i < m; i++) { cout << b[i] << ' '; } cout << endl; return 0; } ``` **打印字符串** ```C++ #include void print(char str[]) { printf("%s", str); } int main() { char str[110]; fgets(str, 101, stdin); //因为需要多输入一个回车,所以多一个字符 print(str); return 0; } ``` **数组翻转** ```C++ #include using namespace std; void reverse(int a[], int size) { for (int i = 0, j = size - 1; i < j; i++, j--) { swap(a[i], a[j]); } } int main() { int a[1000]; int n, size; cin >> n >> size; for (int i = 0; i < n; i++) { cin >> a[i]; } reverse(a, size); for (int i = 0; i < n; i++) { cout << a[i] << ' '; } return 0; } ``` **数组去重** ```C++ #include using namespace std; int get_unique_count(int a[], int n) { int cnt = 0; for (int i = 0; i < n; i++) { bool is_exist = false; for (int j = 0; j < i; j++) { if (a[i] == a[j]) { is_exist = true; break; } } if (!is_exist) { cnt++; } } return cnt; } int main() { int a[1000]; int n; cin >> n; for (int i = 0; i < 1000; i++) { cin >> a[i]; } cout << get_unique_count(a, n) << endl; return 0; } ``` **数组排序** ```C++ #include using namespace std; void sort(int a[], int l, int r) { for (int i = l; i <= r; i++) { for (int j = i + 1; j <= r; j++) { if (a[j] < a[i]) { swap(a[i], a[j]); } } } } int main() { int a[1000]; int n, l, r; cin >> n >> l >> r; for (int i = 0; i < n; i++) { cin >> a[i]; } sort(a, l, r); for (int i = 0; i < n; i++) { cout << a[i] << ' '; } return 0; } ``` **跳台阶** ```C++ #include using namespace std; int n; int ans; void f(int k) { if (k == n) { ans++; } else if (k < n) { f(k + 1); f(k + 2); } } int main() { cin >> n; f(0); cout << ans << endl; return 0; } ``` **走方格** ```C++ #include using namespace std; int n, m; int ans; void dfs(int x, int y) { if (x == n && y == m) { ans++; } else { if (x < n) { dfs(x + 1, y); } if (y < m) { dfs(x, y + 1); } } } int main() { cin >> n >> m; dfs(0, 0); cout << ans << endl; return 0; } ``` **排列** ```C++ #include using namespace std; const int N = 10; int n; void dfs(int u, int nums[], bool st[]) { if (u > n) { for (int i = 1; i <= n; i++) { cout << nums[i] << ' '; } cout << endl; } else { for (int i = 1; i <= n; i++) { if (!st[i]) { st[i] = true; nums[u] = i; dfs(u + 1, nums, st); st[i] = false; } } } } int main() { cin >> n; int nums[N]; bool st[N] = {0}; dfs(1, nums, st); return 0; } ``` 22.01.04二 第六讲 函数 1. 函数基础 一个典型的函数定义包括以下部分:返回类型、函数名字、由0个或多个形参组成的列表以及函数体。 例: ```C++ #include using namespace std; int foo (int n) { // foo是函数名字,int n 参数 类似于定义变量 int res = 1; for (int i = 1; i <= n; i++) { res *=i; } return 0; //不写没问题,但是会出现随机性 } int main() { //int 返回值类型, main 函数名称 int t = foo(5); cout << t << endl; return 0; } ``` **编写函数** 函数名字是fact,它作用于一个整数参数,返回一个整数值。 return语句负责结束fact并返回ret的值。 *求阶乘的程序* ```C++ int fact(int val) { int ret = 1; while (val > 1) { ret *= val--; } return 0; } ``` **调用函数** 函数的调用完成两项工作:一是用实参初始化函数对应的形参, 二是将控制权转移给被调用函数。 此时,主调用函数的执行被暂时中断,被调用函数开始工作。 ```C++ int main() { int j = fact(5); cout << "5!is" << j << endl; return 0; } ``` **形参和实参** 实参是形参的初始化。第一个实参初始化第一个形参,第二个实参初始化第二个形参,依次类推。形参和实参的个数必须匹配。 `fact("hello");` // 错误:实参类型不正确 `fact();` // 错误: 实参数量不足 `fact(42, 10, 0)`// 错误: 实参数量过多 `fact(3.14)` // 正确: 该实参能转换成int类型, 等价于 fact(3) 形参也可以是默认值,但所有默认值必须是最后几个。当传入的实参个数少于形参个数时,最后没有被传入值的形参会使用默认值。 **函数的形参列表** *函数的形参列表可以为空,但不能省略* `void f() {/*······*/}` //隐式地定义空形参列表 `void f(void) {/*······*/}` //显式地定义空形参列表 *形参列表中的形参通常用逗号隔开,其中每个形参都是含有一个声明符的声明* `int f(int v1, v2) {/*······*/}` // 错误 `int f(int v1, int v2) {/*······*/}` // 正确 **函数返回值** 大多数类型都能用作函数的返回值类型。一种特殊的返回类型都是void,它表示函数不反悔任何值。函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。 **局部变量、全局变量与静态变量** 局部变量只可以在函数内部使用,全局变量可以在所用函数内使用,当局部变量与全局变量重名时,会优先使用局部变量。 `静态变量 static int cnt = 0` (可用于统计被调用了多少次) //等于在函数内部开了一个该函数能用的全局变量 2. 参数传递 **传值参数** 当初始化一个非引用类型的变量时,初始值被拷贝给变量。此时,对变量的改动不会影响初始值。 ```C++ #include using namespace std; int max(int x, int y) { if (x, y) { return 0; } } int main() { int x, y; // int x = 10, int y = 20 (不会影响初始值) cin >> x >> y; cout << max(x, y) << endl; return 0; } ``` **传引用参数** 当函数的参数为引用类型时,对形参的修改会影响实参的值。 使用引用的作用:避免拷贝、让函数返回额外信息 ```C++ void swap(int &x, int &y) { int t = x; x = y; y = t; } ``` **数组形参** 在函数中对数组中的值的修改,会影响函数外面的数组 一维数组形参的写法 //尽管形式不同,但这三个print函数是等价的 `void print(int *a) {/*······*/}` `void print(int a[]) {/*······*/}` `void print(int a[10]) {/*······*/}` 例: ```C++ #include using namespace std; int output (int n, int a[5]) { for (int i = 0; i < n; i++) { cout << a[i] << ' '; } cout << endl; } int main() { int a[5] = {1, 2, 3, 4, 5}; output(5, a); return 0; } ``` *函数内部改变 外部也会变* 例: ```C++ #include using namespace std; void foo(int a, int b = 10) { // 第二个参数可以是默认参数 cout << a << ' ' << b << endl; } int main() { foo(5, 3); //不传值就是10,传值就是3 return 0; } ``` **多维数组形参的写法** //多维数组中,除了第一维之外,其余维度的大小必须指定 `void print(int(*a)[10]) {/*······*/}` `void print(int a[10]) {/*······*/}` **返回类型和return语句** *return语句终止当前正在执行的函数并将控制权返回到调用该函数的地方* return; return expression; *如果int 类型,是什么类型就return什么类型(return 类似于循环中的break)* void类型 return 例(调用): ```C++ #iclude using namespace std; void goo() { puts("called goo"); } void foo() { puts("called foo"); goo(); goo(); } int main() { foo(); foo(); return 0; } ``` **函数递归** 函数调用自己叫递归 例: ```C++ #include using namespace std; int fact(int n) { if (n <= 1) { return 1; } return n *fact(n - 1); } int main() { int n; cin >> n; cout << fact(n) << endl; return 0; } ``` 21.12.31五 第五讲 字符串 **字符串匹配** ```C++ #include using namespace std; int main() { double k; string a, b; cin >> k >> a >> b; int cnt = 0; for (int i = 0; i < a.size(); i++) { if (a[i] == b[i]) { cnt++; } } if ((double)cnt / a.size() >= k) { puts("yes"); } else { puts("no"); } return 0; } ``` **忽略大小写比较字符大小** ```C++ #include #include int main() { char a[100], b[100]; fgets(a, 100, stdin); fgets(b, 100, stdin); if (a[strlen(a) - 1] == '\n') { a[strlen(a) - 1] = 0; } if (b[strlen(b) - 1] == '\n') { b[strlen(b) - 1] = 0; } for (int i = 0; a[i]; i++) { if (a[i] >= 'A' && a[i] <= 'Z') { a[i] += 32; } } for (int i = 0; b[i]; i++) { if (b[i] >= 'A' && b[i] <= 'Z') { b[i] += 32; } } int t = strcmp(a, b); if (t == 0) { puts("="); } else if (t < 0) { puts("<"); } else { puts(">"); } return 0; } ``` **去掉多余的空格** ```C++ #include #include using namespace std; int main() { string s; getline(cin, s); string r; for (int i = 0; i < s.size(); i++) { if (s[i] != ' ') { r += s[i]; } else { r += ' '; int j = i; while (j < s.size() && s[j] == ' ') { j++; i = j - 1; } } } cout << r << endl; return 0; } ``` **替换字符** ```C++ #include #include using namespace std; int main() { char str[31]; scanf("%s", str); char c; scanf("\n%c", &c); for (int i = 0; str[i]; i++) { if (str[i] == c) { str[i] = '#'; } } puts(str); return 0; } ``` **信息加密** ```C++ #include #include using namespace std; int main() { string s; getline(cin, s); for (auto &c : s) { if (c >= 'a' && c <= 'z') { c = (c - 'a' + 1) % 26 + 'a'; } else if (c >= 'A' && c <= 'Z') { c = (c - 'A' + 1) % 26 + 'A'; } } cout << s << endl; return 0; } ``` **输出字符串** ```C++ #include #include using namespace std; int main() { string a, b; getline(cin, a); for (int i = 0; i < a.size(); i++) { b += (char)(a[i] + a[(i + 1) % a.size()]); } cout << b << endl; return 0; } ``` **单词替换** ```C++ #include #include using namespace std; int main() { string s, a, b; getline(cin, s); cin >> a >> b; stringstream ssin(s); string str; while (ssin >> str) { if (str == a) { cout << b << ' '; } else { cout << str << ' '; } } return 0; } ``` **字符串连续出现最长的字符** ```C++ #include using namespace std; int main() { int n; cin >> n; while (n--) { string str; cin >> str; int cnt = 0; char c; for (int i = 0; i < str.size(); i++) { int j = i; while (i < str.size() && str[j] == str[i]) { j++; } if (j - i > cnt) { cnt = j - i, c = str[i]; i = j - 1; } } cout << c << ' ' << cnt << endl; } return 0; } ``` **最长单词** ```C++ #include using namespace std; int main() { string res, str; while (cin >> str) { if (str.back() == '.') { str.pop_back(); } if (str.size() > res.size()) { res = str; } } cout << res << endl; return 0; } ``` **倒排单词** ```C++ #include #include using namespace std; int main() { string str[100]; int n = 0; while (cin >> str[n]) { n++; } for (int i = n - 1; i >= 0; i--) { cout << str[i] << ' '; } cout << endl; return 0; } ``` **字符串移位包含问题** ```C++ #include #include using namespace std; int main() { string a, b; cin >> a >> b; if (a.size() < b.size()) { swap(a, b); } for (int i = 0; i < a.size(); i++) { a = a.substr(1) + a[0]; for (int j = 0; j + b.size() <= a.size(); j++) { int k = 0; for (; k < b.size(); k++) { if (a[j + k] != b[k]) { break; } } if (k == b.size()) { puts ("true"); return 0; } } } puts("false"); return 0; } ``` **字符串乘方** ```C++ #include using namespace std; int main() { string str; while (cin >> str, str != ".") { int len = str.size(); for (int n = len; n; n--) { if (len % n == 0) { int m = len / n; string s = str.substr(0, m); string r; for (int i = 0; i < n; i++) { r += s; } if (r == str) { cout << n << endl; break; } } } } return 0; } ``` **字符串最大跨距** ```C++ #include using namespace std; int main() { string s, s1, s2; char c; while (cin >> c, c != ',') { s += c; } while (cin >> c, c != ',') { s1 += c; } while (cin >> c) { s2 += c; } if (s.size() < s1.size() || s.size() < s2.size()) { puts("-1"); } else { int l = 0; while (l + s1.size() <= s.size()) { int k = 0; while (k < s1.size()) { if (s[l + k] != s1[k]) { break; } k++; } if (k == s1.size()){ break; } l++; } int r = s.size() - s2.size(); while (r >= 0) { int k = 0; while (k < s2.size()) { if (s[r + k] != s2[k]) { break; } k++; } if (k == s2.size()) { break; } r--; } l += s1.size() - 1; if (l >= r) { puts("-1"); } else { printf("%d\n", r - l - 1); } } return 0; } ``` **最长字符串后缀字符** ```C++ #include using namespace std; const int N = 200; int n; string str[N]; int main() { while (cin >> n, n) { int len = 1000; for (int i = 0; i < n; i++) { cin >> str[i]; if (len > str[i].size()) { len = str[i].size(); } } while (len) { bool success = true; for (int i = 1; i < n; i++) { bool is_same = true; for (int j = 1; j <= len; j++) { if (str[0][str[0].size() - j] != str[i][str[i].size() - j]) { is_same = false; break; } } if (!is_same) { success = false; break; } } if (success) { break; } len--; } cout << str[0].substr(str[0].size() - len) << endl; } return 0; } ``` 21.12.10五 第五讲 字符串 **字符串的长度** ```C++ #include int main() { char str[101]; fgets(str, 101, stdin); // 想把一行都读入到字符串里用fgets int len = 0; for (int i = 0; str[i] && str[i] != '\n'; i++) { // 不能自动空格 len++; } printf("%d\n", len); return 0; } ``` 注意:fgets 用法,需要自己过滤空格 **字符串中的数字个数** ```C++ #include int main() { char str[101]; fgets(str, 101, stdin); int cnt = 0; for (int i = 0; str[i]; i++) { if (str[i] >= '0' && str[i] <= '9') { cnt++; } } printf("%d\n", cnt); return 0; } ``` 注意:难点在于如何判断字符串里的数字 **循环相克令** ```C++ #include #include using namespace std; int main() { int n; cin >> n; while (n--) { string a, b; cin >> a >> b; int x, y; if (a == "Hunter") { x = 0; } else if (a == "Bear") { x = 1; } else { x = 2; } if (b == "Hunter") { y = 0; } else if (b == "Bear") { y = 1; } else { y = 2; } if (x == y) { puts("Tie"); } else if (x == (y + 1) % 3) { puts("Player1"); } else { puts("Player2"); } } return 0; } ``` 注意:需要把这三个变成数,得到规律,后用x y 来表示。 **字符串插入** ```C++ #include using namespace std; int main() { string a, b; while (cin >> a >> b) { int p = 0; for (int i = 1; i < a.size(); i++) { if (a[i] > a[p]) { p = i; } } cout << a.substr(0, p + 1) + b + a.substr(p + 1) << endl; } return 0; } ``` 注意:难点在于如何找到字符串中最大的内个数,还有a.substr(0, p + 1)应用。 **字符串加空格** ```C++ #include using namespace std; int main() { string a; getline(cin, a); // 因为字符串中包含空格,所以用getline string b; for (auto c : a) { // 枚举a里面的每一个数 b = b + c + ' '; } cout << b << endl; return 0; } ``` 注意:需要从左往右加,所以一定要保证有string **只出现一次的字符** ```C++ #include #include #include using namespace std; int cnt[26]; char str[100010]; int main() { cin >> str; int len = strlen(str); for (int i = 0; i < len; i++) { cnt[str[i] - 'a']++; } for (int i = 0; i < len; i++) { if (cnt[str[i] - 'a'] == 1) { cout << str[i] << endl; return 0; } } puts("no"); return 0; } ``` 21.12.08三 今天把字符串的课给听完了,大体了解字符串,但是熟练运用很困难。需要记的点比较多,想要熟练运用还是需要多做题,锻炼自己的逻辑能力。需要多琢磨你想要编译出来的东西,你所需要做的大体步骤有哪些,整理清楚自己的思路是刚开始,如何用代码来表示更加困难。需要在之前学过的基础上来进行现在的学习,所以也不要恐惧自己没有学会之前的东西,查缺补漏嘛,不行再学呗。 第五讲 字符串 2. 字符数组 **练习:给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符,如果没有输入“no"** 主要思路: (1)需要先读入一个字符串,还要有如何读字符串 (2)如何辨别字符串里,每一个字符 (3)如何统计字符出现的次数 a ~ z 与0 ~ 25相对应 ```C++ #include #include using namespace std; int cnt[26]; char str[100010]; // 全局变量 int main() { cin >> str; for (int = 0; i < strlen(str); i++) { // strlen(str)是字符串的长度, cnt[str[i] - 'a']++; // 注意;这里a与0相对应 } for (int i = 0; i < strlen(str); i++) { // strlen(str)需要每执行一次,判断一次,输出一次 if (cnt[str[i]- 'a'] == 1) { cout << str[i] << endl; return 0; } } puts("no"); return 0; } ``` 第二种方法 ```C++ #include #include using namespace std; int cnt[26]; char str[100010]; int main() { cin >> str; int len = strlen(str); // 先用len定义一下strlen就会快很多 for (int i = 0; i < len; i++) { cnt[str[i] - 'a']++; } for (int i = 0; i < len; i++) { if (cnt[str[i] - 'a'] == 1) { cout << str[i] << endl; return 0; } } puts("no"); return 0; } ``` 第三种方法 ```C++ #include #include using namespace std; int cnt[26]; char str[100010]; int main() { cin >> str; int len = strlen(str); // 先用len定义一下strlen就会快很多 for (int i = 0; str[i]; i++) { cnt[str[i] - 'a']++; } for (int i = 0; str[i]; i++) { if (cnt[str[i] - 'a'] == 1) { cout << str[i] << endl; return 0; } } puts("no"); return 0; } ``` **练习:把一个字符串中特定的字符全部用给定的字符替换,得到一个新的字符串** 主要思路; 由于由大小写字符构成 没有空格用 cin / scanf 有空格 gentline / cin.gentline /fgets 还有:puts在 里 ```C++ #include #include using namespace std; int main() { char str[31]; scanf("%s", str); // 读到字符串里面 char c; scanf("\n%c", &c); // 再读一个要替换的字符,因为scanf不可以自动过滤掉空格,所以要自己加上 for (int i = 0; str[i]; i++) { if (str[i] == c) { str[i] == '#'; } } puts(str); return 0; } ``` 3. 标准库类型 string(很强大的字符串的处理工具) 可变长的字符序列,比字符数组更加好用,需要引入头文件 #include **定义和初始化** ```C++ #include #include using namespace std; int main() { string s1; // 默认初始化,s1是一个空字符串 string s2 = s1; // s2是s1的副本 string s3 = "hiya"; // s3是该字符字面值的副本 string s4 = (10, 'c'); // s4内容是cccccccccc return 0; } ``` *输出可用 printf("%s\n",s.c_str())* *函数 s.c_str() :会返回s字符串它存储字符串字符数组的首地址* **string上的操作** string 的读写 ```C++ #include #include using namespace std; int main() { string s1, s2; cin >> s1 >> s2; cout << s1 << s2 << endl; // 注意:不能用printf直接输出string, 需要写成 printf("%s", s.c str()); return 0; } ``` **使用getline读取一整行** ```C++ #include #include int main() { string s; gtline(cin, s); cout << s << endl; return 0; } ``` **string 的 empty 和 size 操作(注意:size 是无符号整数,因此 s.size( ) <= -1 一定成立)** ```C++ #include #include using namespace std; int main() { string s1, s2 = "abc"; cout << s1.empty() << endl; cout << s2.empty() << endl; cout << s2.size( ) << endl; return 0; } ``` **string 的比较(按照字典序比较)** 支持< > =< >= == != 等所有比较操作 ```C++ string s1, s2; if (s1 == s2) ``` **为string 对象赋值 (可以累加,只有加法操作,可加字符串和加字符)** ```C++ string s1 (10, 'c'), s2; // s1的内容是cccccccccc; s2是一个空字符串 s1 = s2 // 赋值: 用s2的副本替换s1的副本 // 此时s1和s2都是空字符 ``` **两个string对象相加** ```C++ string s1 = "hello", s2 = "world\n"; string s3 = s1 + s2; // s3的内容是 hello,world s1 += s2; // s1 = s1 + s2 ``` **字面值和string对象相加,类型转化** 做加法运算时,字面值和字符都会转化成string对象,因此直接相加就是将这些字面值串联起来 ```C++ string s1 = "hello", s2 = "world"; // 在s1和s2中没有标点符号 string s3 = s1 + "," + s2 + '\n'; ``` *当把string对象和字符字面值及字符串字面值混在一调语句中使用时,必须确保,每个加法运算符和两侧的运算对象至少有一个string* ```C++ string s4 = s1 + ","; // 正确:把一个string对象和有一个字面值相加 string s5 = "hello" + ","; // 错误:两个运算都不是string string s6 = s1 + "," + "world"; // 正确: 每个加法运算都有一个string string s7 = "hello" + "," + s2; // 错误:不能把字面值直接相加,运算是从左到右 ``` **处理string对象中的字符** 可以将string对象当成字符数组来处理 ```C++ #include #include using namespace std; int main() { string s = "hello, world"; for (int i = 0; i < s, size(); i++) { cout << s[i] << endl; } return 0; } ``` ```C++ for (char c : s) { // 基于范围的for语句 cout << c << endl; } ``` 21.12.04六 第五讲 字符串 1. 字符与整数的联系 ——ASCⅡ码 每个常用字符都对应一个-128 —— 127的数字,二者之间可以相互转化。(整数可变字符,字符可变整数) ```C++ #include using namespace std; int main() { char c = 'a'; cout << (int)c << endl; // a在计算机里存的值为97 cout << (char)97 << endl; return 0; } ``` ```C++ #include using namespace std; int main() { for (int i = 1; i < 128; i++) { // 通过循环之后就可以看到每个整数对应的字符 printf("%d=%c\n", i, (char)i); } return 0; } ``` **也可以做两个浮点数的差** ```C++ printf("%d\n", 'z' - 'a'); ``` 我们可以理解为:char其实存整数,但是计算机回自动把数字转化为字符输出到屏幕上。 **常用ASCⅡ值'A'-'z'是65-90,'a'-'z'是97-122,'0'-'9'是48-57。** **字符可以参与运算,运算时会将其当作整数** ```C++ #include using namespace std; int main() { int a = 'B' - 'A'; int b = 'A' * 'B'; int c = 'A' + 2; cout << a << endl; cout << b << endl; cout << c << endl; return 0; } ``` **练习:输入一行字符,统计出其中数字字符的个数,以及字母字符的个数** ```C++ #include using namespace std; int main() { char c; int nums = 0, chars = 0; while (cin >> c) { if (c >= '0' && c <= '9') { nums++; } else if (c >= 'A' && c <= 'Z' || c >= 'a' && c <='z') { chars++; } } printf("nums:%d\n char:%d\n", nums, chars); return 0; } ``` 2. 字符数组 字符串就是字符数组加上结束符'\0'(规定以 \0 结束、\0 阿斯克码值为0) 可以使用字符串来初始化字符数组,但此时要注意,每个字符串结尾会暗含一个'\0'字符,因此字符数组的长度至少要比字符串的长度多1! **初始化** ```C++ #include using namespace std; int main() { char a1[ ] = {'C', '+', '+'}; // 列表初始化,没有空字符 char a2[ ] = {'C', '+', '+'}; // 列表初始化,含有显示的空字符 char a3[ ] = "C++"; // 自动添加表示字符串结尾的空字符 char a4[ ] = "Daniel"; // 错误:没有空间存放空字符! return 0; } ``` (a2与a3初始化方式等价) 以a2为例 若想从'c'开始输出,则写: cout << a2 << endl; 若从'+'开始输出 ,则写: cout << a2+1 << endl; **字符数组的输入输出** ```C++ #include using namespace std; int main() { char str[100]; cin >> str; // 输入字符串时,遇到空格或者回车就会停止! cout << str << endl; printf("%s\n", str); return 0; } ``` **如果想把一行读入字符串里用fgets** ```C++ #include #include using namespace std; int main() { char s[100]; fgets(s, 100, stdin); // 100表示:最多读入多少字符 cout << s << endl; return 0; } ``` ```C++ string s; getline (cin, s); // 可以用getline输入 ``` ```C++ char s[100]; cin.getline(s, 100); // 输入数组可以用cin.getline ``` ```C++ puts (s); ``` **字符数组的常用操作** 下面几个函数需要引用头文件 #include 基本时C的头文件 strlen(str) 求字符串的长度 // 不包括\0字符 strcmp(a, b), 比较两个字符串的大小,a < b返回-1,a == b返回0,a > b返回1。 这里的比较方式是字典序! strcpy(a, b), 将字符串b复制给从a开始的字符数组。 21.12.01三 第四讲 数组 **平方矩阵** 平方矩阵Ⅰ ```C++ #include using namespace std; int main() { int n; while (cin >> n, n) { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { int up = i, down = n - i + 1, left = j, right = n - j + 1; // 与上下左右之间的距离 cout << min(min(up, down), min(left, right)) << ' '; } cout << endl; } cout << endl; } return 0; } ``` 平方矩阵Ⅱ ```C++ #include #include #include using namespace std; const int N = 110; int n; int a[N][N]; int main() { while (cin >> n, n) { for (int i = 1; i <= n; i++) { for (int j = i, k = 1; j <= n; j++, k++) { a[i][j] = k; a[j][i] = k; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cout << a[i][j] << ' '; } cout << endl; } cout << endl; } return 0; } ``` 平方矩阵Ⅲ ```C++ #include #include using namespace std; int main() { int n; while (cin >> n, n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { int v = 1; for (int k = 0; k < i + j; k++) { v *= 2; } cout << v << ' '; } cout << endl; } cout << endl; } return 0; } ``` 21.11.29一 第四讲 数组 **关于例题数组的某部分** ```C++ #include int main() { char t; scanf("%c", &t); double a[12][12]; for (int i = 0; i < 12; i++) { // 首先存入数组 for (int j = 0; j < 12; j++) { scanf("%lf", &a[i][j]); // 读出 } } int c = 0; double s = 0; for (int i = 0; i < 12; i++) { // 行的起始位置,和终止位置 for (int j = i + 1; j < 12; j ++) { // 列的起始与终止位置 c++; s += a[i][j]; } } if (t == 'S') { printf("%.1lf\n", s); } else { printf("%.1lf\n", s / c); } return 0; } ``` 数组的某方区域 ```C++ #include int main() { char t; double a[12][12]; scanf("%c", &t); for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { scanf("%lf", &a[i][j]); } } double s = 0, c = 0; for (int i = 0; i < 5; i++) { for (int j = i + 1; j <= 10 - i; j++) { c += 1; s += a[i][j]; } } if (t == 'S') { printf("%.1lf\n", s); } else { printf("%.1lf\n", s / c); } return 0; } ``` 这种类型的题,前面套路相同需要把数组、总和等都定义出来。不同点在于:行的起点与终点,列的起点与终点不同。需要找到规律。求区域的要更加复杂一些,要把分成两部分来找其规律,总体来说,明白一个就可以掌握全部。(但是每回都会有小的错误,说明逻辑还是不够清晰) 21.11.25四 第四讲 数组 2. 多维数组 (数组的数组) int a[3][4]; //大小为3的数组,每个元素是含有4个整数的数组 int arr[10][20][30] = {0}; //将所有元素初始化为0 //大小为10的数组,它的每个元素是含有4个整数的数组 //这些数组的元素是含有30个整数的数组 **二维数组初始化** ```C++ #include #include using namespaced std; int main() { int a[3] = {0, 1, 2}; int b[3][4] = { {1, 2, 3, 4} {2, 2, 3, 4} {3, 2, 3, 4} } for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { cout << b[i][j] <<' '; cout << endl; } } return 0; } ``` **方便清空数组** **memse所有单位都是字节** **sizeof 运算符** 类似于 -2 、!2 (2前面的内个符号) sizeof a (不需要打括号) //用来求一个数组所占用的字节数量 memcpy (b, a, sizeof a); //b复制的目标数组 //a原数组 这部分记的比较乱,等今天把数组的习题学完,再回来补充。 **例题** 数组替换 ```C++ #include int main() { int x[10]; for (int i = 0; i < 10; i++) { scanf ("%d", &x[i]); } for (int i = 0; i < 10; i++) { if (x[i] <= 0) { x[i] = 1; } } for (int i = 0; i < 10; i++) { printf("X[%d] = %d\n", i, x[i]); } return 0; } ``` 注意:观察输出是否麻烦,用printf会比较简单 把x[i]看作一个变量,如何读变量就如何读x[i] 数组选择 ```C++ #include int main() { double a[100]; for (int i = 0; i < 100; i++) { scanf ("%lf", &a[i]); } for (int i = 0; i < 100; i++) { if (a[i] <= 10) { printf("A[%d] = %.1lf\n", i, a[i]); } } return 0; } ``` 数组中的行 ```C++ #include int main() { double a[12][12]; int l; char t; scanf ("%d\n%c", &l, &t); for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { scanf ("%lf", &a[i][j]); } } double s = 0; for (int i = 0; i < 12; i++) { s += a[l][i]; } if (t == 'S') { printf("%.1lf\n", s); } else { printf("%.1lf\n", s / 12); } return 0; } ``` 注意:scanf不会过滤掉空格回车 数组中的右上半部分 ```C++ #include int main() { char t; scanf("%c", &t); double a[12][12]; for (int i = 0; i < 12; i++) { for (int j = 0; j < 12; j++) { scanf ("%lf", &a[i][j]); } } int c = 0; double s = 0; for (int i = 0; i < 12; i++) { for (int j = i + 1; j < 12; j++) { c++; s += a[i][j]; } } if (t == 'S') { printf("%.1lf\n", s); } else { printf("%.1lf\n", s / c); } return 0; } ``` 1. 先把所有数读出来 2. 需要类型 3. 算总和 4. 一行一行统一 **注意如果不是全局变量,记得在循环中重新定义,才能编译出来** 21.11.21日 第四讲 数组 1. 一维数组 (一次性定义多个变量) **数组定义与变量相似** ```C++ int a[ ]; //[]内是数组长度 float c[ ]; char e[ ]; //字符串 string g[ ]; ``` **数组初始化(在main函数内部,未初始化的数组中的元素是随机的):** ```C++ #include #include using namespace std; int main() { int a[3] = {0, 1, 2}; //含有3个元素的数组,元素分别是0,1,2 int b[ ] = {0, 1, 1}; //维度是3的数组 int c[5] = {0, 1, 2}; //等价于c[ ] = {0, 1, 2, 0,0} char d[3] = {'a', 'b', 'c'}; //字符数组的初始化 return 0; } ``` **局部变量的值可以是随机的,全局变量的值都是0** ```C++ #include using namespace std; int main() { int a[100] = {0}; //数组下标一定从0开始 int b; int c = a[0] * 2; cout << a[0] << endl; return 0; } ``` **练习1 使用数组实现求斐波那契数列的第N项** ```C++ #include #include using namespace std; int main() { int f[100]; f[0] = 0, f[1] = 1; int n; cin >> n; for (int i = 2; i <= n; i++) { f[1] = f [i - 1] + f[i -2]; } cout << f[n] << endl; return 0; } ``` **联系2 输入一个n,再输入n个整数,将这个n个整数逆序输出** 比如:输入5个数 1 2 3 4 5 输出 5 4 3 2 1 *两次for循环* ```C++ #include using namespace std; int main() { int a[100]; int n; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; //调整数组的顺序 for (int i = n - 1; i >= 0; i--) //倒着循环一遍 cout << a[i] <<' '; cout << endl; return 0; } ``` 注意:第一次排序后,想要逆序输出,要搞明白最后一个数如何表示。 **旋转** 例:一次旋转 1 2 3 4 5 5 1 2 3 4 **联系题3:输入一个n,再输入n个整数,将这个数组顺时针旋转k(k<=n)次,最后将结果输出。** 普通旋转的做法 ```C++ #include using namespace std; int main() { int a[100]; int n, k; cin >> n >> k; for (int i = 0; i < n; i++) cin >> a[i]; //调整这个数组的顺序 while (k--) { int t = a[n -1]; for (int i = n - 2; i >= 0; i--) { a[i + 1] = a[i]; } a[0] = t; } for (int i = 0; i < n; i++) cout << a[i] << ' '; return 0; } ``` 用reverse来做 ```C++ #include #include using namespcae std; int main() { int n, k; int a[100]; cin >> n >> k; for (int = 0; i < n; i++) cin >> a[i]; reverse (a , a+k); //a表示起始位置,a+k表示终止位置 return 0; } ``` 巧妙做法 ```C++ #include #include using namespace std; int main() { int a[100]; int n, k; cin >> n >> k; for (int i = 0; i < n; i++) cin >> a[i]; reversw (a, a + n); //翻转整个数组 reverse (a, a + k); //翻转前半部分 reverse (a + k, a + n); //翻转后半部分 for (int i = 0; i < n; i++) cout << a[i] <<' '; return 0; } ``` 注意整个逻辑,来回翻转容易搞晕,通过画图,来帮助理解。 21.11.18四 1. 局部变量的值可以是随机的,全局变量的值都是0 今日看了整体的第三讲习题课和第四讲的网课,明天看数组的习题课,打算整体看一遍再去做习题。 21.11.15一 今天继续学循环,要注意题中循环次数,要思考哪一个是外循环,哪一个应该是内循环。还有判断和循环的熟练应用。再就是有的只需要定义,不需要输入,我总是搞混。要注意!!! 21.11.14日 1. C++有运算速度上限 1秒 < 1亿次 重新看一遍第三课的习题,解决不懂的问题,复习一遍。还有三道题没看,明天来搞明白。 21.11.13六 1. 格式化输出尽量用 printf 来写 2. scanf 与 cin 的区别:scanf 读入一个字符时,不会过滤掉空格 回车 tab 3. if (a <= x && x < = b) C++中比较运算符只能比较两个 不可 a <= x <= b 否则 成立为1 不成立则为0 4. 只想循环n次,且n以后不会再用可写( n-- ) 照葫芦画瓢容易,真正明白里面的逻辑难,希望可以真的让自己循序渐进,脚踏实地。(自我欺骗太可怕了) 21.11.11四 1. swap(x , y)也可表示x和y相互交换,swap是``这个文件中的 今天做了八道题,感觉对循环语句还是比较模糊的印象,但是并不复杂,明天把所有这部分习题全部打卡。再重新自己做一遍。 21.11.10三 1. 学习 跳转语句`break`和`continue`,了解它们之间的区别。 2. 取绝对值 `abs(x)` 或判断一下 `if (x < 0) x = -x` 3. 例题:712正数 (for循环和if语句的结合) y总说有许多背的东西的时候,本质是人类在创造这门语言的时候,没想清楚,会有很多个例出现。 21.11.09二 1. `"ctrl" + "/"` 为 注释 快捷键 2. while、do-whlie、for 都是等价的 今天学习循环语句,笔记太多就不打上去了。课看一半,预计明天看完。没有掌握结构,得好好练习诶。 21.11.08一 今天主要任务把这几天的题自己独立做了一下。很多时候我们总是想要快速掌握一些知识,并没有踏踏实实的去学习,自欺欺人的认为把题全部提交了就是学会了。实际上,就是无脑搬运别人思考之后的东西。只有自己不断去尝试才能收获到你真正学习到的东西。还有不计其数一看就会,一做就废的“小细节”,即便再做一遍也会发现很多问题。所以一定要踏踏实实的去学习!!! 例: 开始写成:`if(x < 0 && x > 100)`(根本不存在这样的数!) 21.11.07日 今天,把题算是都做完了,但是实际上我只是仿照y总的打上去,并没有太多自己的思考,下一阶段不看视频自己独立做一边这节课的东西。还有就是看y总视频发现,有很多时候我们需要在做题的过程中发现需要用到的头文件,而不是一开始就知道需要用哪些,还要思考用什么输入输出要较为方便。需要的是清晰的思路,然后一步一步去完成,最后编译出来。 21.11.05五 1. 特殊字符输出格式时需要转义,前面加`'\'` 2. 格式化输出需要用`printf`来输出 3. 把a b c按从大到小排序 `if(a > b) 交换 a b ` `if (c > a) 交换 c a` `if (c < b) 交换 c b` $a <= b <= c$ 今天原本打算把第二节课的习题都做完的,主要是看视频然后做题,虽然是把题给提交了,但是如果不看答案做的话,估计还是不行。还是得多做几遍的,还有对这个题目的分析,额,救命。得自己完全做出来才算是能稍微掌握。 21.11.04四 今天做了判断语句的习题,要注意大于小于,尤其是`'a != b'`,如何表示。还有`'&&` `||` `!'`熟练运用。 21.11.03三 1. `printf`另一用法,想让整个所有数对齐,设置变量,宽度相等。 2. 今天学习了判断语句,if语句后面不能加`;` 3. 当if/else之间只有一句话,即可以省略大括号 4. if语句内部可嵌套if语句 今天把y总判断语句课看完,感觉还阔以,主要是得多练,做了三道题。 21.11.02二 1. 万能头文件`include ` 2. 只用scanf 和 printf的话,可以不加 using namespace std 3. C++可以编译所有C的代码,C不一定可以编译C++的代码 今天从头到尾的看了y总的习题课,比起做题看的一个一个片段,逻辑要更加清晰。他反复重复学习语法要多练习。 21.11.01一 1. 存字符串用 用 `cin`来读 2. 在C中,scanf和printf等基本输入输出的函数被定义在stdio.h这个头文件里,stdio 的意思是:`standard input output` 基本输入输出。类似的,C中的头文件 stdlib.h,在C++里就可以用 cstdlib 来使用。 3. `abs`函数,返回两数绝对值 第一课题全部做完了,需要更仔细认真一点。 21.10.31日 1. 要看视频做记录,不要拉视频,优先视频讲解 2. 已经能够稍微了解格式书写,但是远远不够 3. 看到别人打卡的,每道题解决的方式很多,不断补充积累 行了叭叭不出来了,我感觉今天没有学到太多东西吧,晚上见。 21.10.30六 1. 可以把整数读到浮点数中,但浮点数不能读到整数中 2. 所有和数学相关的函数用 `cmath` 3. C++中不可以 用`^2`表示平方 起初觉得抽象无从下手,现在觉得就是跟背公式有一些相似,掌握问题中想要如何去做套用进去,要不断积累套用的模板,并能够通过看问题,想到需要用的类型。编译成功后尝试替换。 21.10.29五 1. 声明变量类型(浮点:99%用double) 2. 需要保留小数点几位的,用scanf printf > (scanf 是 scan function printf 是 print function) 3. 计算 | 类型1 | 类型2 | 结果 | | ----- | ------ | ------ | | 整数 | 小数 | 小数 | | char | int | int | | int | long | long | | float | double | double | 4. 熟悉结构和含义,找逻辑,通过题目尝试做一下,举一反三。。。 21.10.28四 1. 注册了github账号,建立了这个学习C++的仓库 2. 看了y总的语法基础课试听课视频,拼团成功