查看当前分支
git branch -- show-current
1 | #include <stdio.h> |
预处理阶段:预处理器根据#开头的命令,读取头文件,并插入到程序中,得到.i文件
1 | # 1 "hello.c" |
编译阶段:编译器将hello.i翻译成文本文件hello.s
1 | .arch armv8-a |
汇编阶段:汇编器将hello.s翻译成机器语言的指令,将结果保存在.o文件中
链接阶段:hello.c文件中调用了printf()函数,printf函数存在于printf.o的程序中,链接器负责处理合并,得到可执行文件
1 | vector<bool> is_prime(n, true); |
1 | void bubble_sort(std::vector<int>& nums) { |
1 |
|
1 | struct TreeNode { |
1 | #include <iostream> |
1 | #include <iostream> |
1 | // 不使用+-来计算两数之和 |
问题描述:给定 n 个物品,第 i 个物品的重量为 wgt[i−1]、价值为 val[i−1] ,和一个容量为 cap 的背包。每个物品只能选择一次,问在限定背包容量下能放入物品的最大价值。
定义状态:[i, c],物品编号i和背包容量c
对于当前物品,有两种方案
不放入背包:[i, c] = [i - 1, c]
放入背包:[i, c] = [i - 1, c - weight[i - 1]],价值增加val[i];
dp[i,c]=max(dp[i−1,c],dp[i−1,c−wgt[i−1]]+val[i−1]
给你字符串 s
和整数 k
。
请返回字符串 s
中长度为 k
的单个子字符串中可能包含的最大元音字母数。
例如s = "abciiidef", k = 3
从左到右遍历 s。
首先统计前 k−1=2 个字母的元音个数,这有 1 个。
s[2]=c 进入窗口,此时找到了第一个长为 k 的子串 abc,现在元音个数有 1 个,更新答案最大值。然后 s[0]=a 离开窗口,现在元音个数有 0 个。
s[3]=i 进入窗口,此时找到了第二个长为 k 的子串 bci,现在元音个数有 1 个,更新答案最大值。然后 s[1]=b 离开窗口,现在元音个数有 1 个。
s[4]=i 进入窗口,此时找到了第三个长为 k 的子串 cii,现在元音个数有 2 个,更新答案最大值。然后 s[2]=c 离开窗口,现在元音个数有 2 个。
s[5]=i 进入窗口,此时找到了第四个长为 k 的子串 iii,现在元音个数有 3 个,更新答案最大值。然后 s[3]=i 离开窗口,现在元音个数有 2 个。
s[6]=d 进入窗口,此时找到了第五个长为 k 的子串 iid,现在元音个数有 2 个,更新答案最大值。然后 s[4]=i 离开窗口,现在元音个数有 1 个。
s[7]=e 进入窗口,此时找到了第六个长为 k 的子串 ide,现在元音个数有 2 个,更新答案最大值。然后 s[5]=i 离开窗口,现在元音个数有 1 个。
s[8]=f 进入窗口,此时找到了第七个长为 k 的子串 def,现在元音个数有 1 个,更新答案最大值。遍历结束。
步骤:
入:下标为 i 的元素进入窗口,更新相关统计量。如果 i<k−1 则重复第一步。
更新:更新答案。一般是更新最大值/最小值。
出:下标为 i−k+1 的元素离开窗口,更新相关统计量。
代码:
1 | class Solution { |
给定一个字符串 s
,请你找出其中不含有重复字符的 最长 子串 的长度。
1 | int lengthOfLongestSubstring(string s) { |
给你一个字符串 s
,它只包含三种字符 a, b 和 c 。
请你返回 a,b 和 c 都 至少 出现过一次的子字符串数目。
1 | int numberOfSubstrings(string s) { |
现在的已经满足了,更长的子串就满足,+left
给你一个整数数组 nums
和一个整数 k
,请你返回子数组内所有元素的乘积严格小于 k
的连续子数组的数目。
1 | int numSubarrayProductLessThanK(vector<int>& nums, int k) { |
长的合法,长的所有子串都合法,+ right - left + 1
例如,要计算有多少个元素和恰好等于 k 的子数组,可以把问题变成:
计算有多少个元素和 ≥k 的子数组。
计算有多少个元素和 >k,也就是 ≥k+1 的子数组。
答案就是元素和 ≥k 的子数组个数,减去元素和 ≥k+1 的子数组个数。这里把 > 转换成 ≥,从而可以把滑窗逻辑封装成一个函数 f,然后用 f(k) - f(k + 1) 计算,无需编写两份滑窗代码。
1 | int my_fun(vector<int>& nums, int goal) { |
1 | mid = left + (right - left) / 2; //避免溢出 |
1 | // lower_bound,指向第一个 ≥ value 的元素的迭代器。 |
1 | auto it = lower_bound(nums, target); //二分,返回的是迭代器,值为*it |
1 | // upper_bound,指向第一个 > value 的元素的迭代器。 |
首先判断sleep是否有参数,将argv[1]
转换为int类型,使用系统调用sleep实现
1 | 1 #include "kernel/types.h" |
建立两个管道,fd1
, fd2
,通过read
和write
实现父进程和子进程之间的通信
1 | 1 #include "kernel/types.h" |
在main函数中的父进程中输入2~35,在main函数的子进程中递归调用filter函数
在filter函数中,首先读的一定是质数,直接输出,通过这个prime判断其他数是否读入到下一个进程中
每个父进程都要写wait,否则会超时
1 | 1 #include "kernel/types.h" |
find
用法:find current_path target
fmtname
作用:根据当前路径返回最后一个/
后的内容
通过st.type
判断是文件还是目录
文件,与target进行比对,相同输出当前路径
目录,递归使用find,构造路径
1 | #include "kernel/types.h" |
xargs
的用法:echo a | xargs echo b,输入 b a,将前一个命令的输出作为后一个命令的参数
注意:下面代码中argv[0]是xargs
使用fork和exec使得新的进程得到执行
1 | #include "kernel/types.h" |
报错信息
kex_exchange_identification: read: Connection reset by peer Connection reset by ::1 port 3316
使用vscode链接docker后在终端输入以下命令
1 | sudo service ssh restart |
const位于星号左侧,const用于修饰指针指向的变量;const位于星号右侧,const修饰指针本身
1 | int b = 500; |
1和2是等价的,都表示指向常量的指针,3表示指针本身不可变,但是指向的内容可变
1 | int a = 10; |
1 | int a |
被static修饰的变量只能在当前文件访问,函数同理
1 | // a.cpp 文件 |
修饰局部变量
1 | void foo() { |
用于声明外部变量
File1.c
1 | #include <stdio.h> |
file2.c
1 | #include <stdio.h> |
函数同理,extern还可以链接c和c++,用extern声明一个函数是c语言,则该函数可以在c++文件中使用
c
1 | #include <stdio.h> |
c++
1 | #include <iostream> |
1 | #include<vector> |
1 | const char* str = "abc"; |
stoi提供了更安全的方式
1 | #include <cctype> |
哈希表
1 | // 声明 |
1 | //基础用法 |
1 | int a = 10; |
b是a的引用,就是给a起个别名,对b进行操作实际上就是对a进行操作
1 | int* a = null; |
指针可以指向空,但是引用不能为空
1 | int a = 10; |
指针可以随意改变(除const修饰外),引用一旦绑定就不可以再改变
.cpp文件经过预处理成为.i文件,.i文件经过编译后成为.s文件,.s文件经过汇编后成为目标文件,即.o,静态链接将该.o文件和其他目标文件以及库文件链接起来,这个过程称为静态链接。
而动态链接将这个过程推迟到了运行时,由操作系统装载程序加载库
静态链接的代码装载速度快,但是文件体积大
动态链接的速度慢,但是文件体积小
释放new申请的空间,会调用析构函数
1 | #include <iostream> |
访问全局变量
1 | #include <iostream> |
访问命名空间中的标识符
1 | #include <iostream> |
public
:可以在任何函数中访问
protected
:只能在类中或者类的子类中访问
private
:只能在类中访问
1 | char ch[] = "Hello World"; |
对于char ch[]类型,是c风格的字符串,在末尾会自动加\0
sizeof会统计末尾的\0
strlen不统计
string在堆上分配内存,sizeof获取的是string类的大小
char ch[]在栈上分配内存
通常是指一种自然地随文化演化的语言。自然语言是人类交流和思维的主要工具,是人类智慧的结晶
是计算机科学领域与人工智能领域中一个重要的方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法
机器学习指的是计算机通过某项任务的经验数据提高了在这项任务上的能力
机器学习是让机器学会算法的算法
语料库是指经科学取样和加工的大规模电子文本库
由人工正确切分后的句子集合
切分并为每个词语制定一个磁性的语料
人工标注了文本内部制作者关心的实体名词以及实体类别
构建一份语料库的过程
语言模型是用来计算一个句子的概率的概率模型
是一种人工智能模型,旨在理解和生成人类语言。它们在大量的文本数据上进行训练,可以执行广泛的任务,包括文本总结、翻译、情感分析等。
序列标注指的是给定一个序列x= x1 x2 x3 x4… 找出序列中每个元素对应的标签y = y1 y2 y3 y4 ….的问题
y所有可能的取值集合称为标注集
隐马尔可夫模型、条件随机场、深度学习模型
指的是预测样本所属类别的问题
指的是将给定对象的集合划分为不同子集的过程
数据预处理
排重
大众化推荐
人工抽查
更大的n:对下一个词出现的约束信息更多,更大的辨别力
更小的n:在训练语料库中出现的次数更多,更可靠的统计结果,更高的可靠性
Transformer是一种用于自然语言处理(NLP)和其他序列到序列(sequence-to-sequence)任务的深度学习模型架构。
序列到序列是指将一个序列转换为另一个序列到任务
执行exit系统调用后,进程会从运行状态转为僵尸状态(zombie),操作系统会销毁当前进程,释放资源
exit
是c标准库的函数,_exit
是系统调用,直接终止进程,不进行清理工作
僵尸进程
: 进程已经终止,但是父进程还未回收其状态信息
将当前进程的地址空间替换为新的程序,但保留当前进程的pid
与fork
配合使用,可以在子进程中运行一个新的程序
fork的作用是在当前进程下,创建一个新的进程,通常把这两个进程称为父进程和子进程,子进程的内存是复制父进程的,它们有独立的内存空间,fork在父进程中返回的值为子进程的pid,在子进程中返回的值为0,这就是为什么pid == 0可以判断它是子进程
1 | int pid; |
通过fork实现父子进程之间的读和写
read(fd[0], buf, sizeof(buf));
write(fd[1], buf, sizeof(buf));
注意:默认情况下读用0,写用1,管道是单方向的,要实现两端的读和写需要两个管道,buf是指向缓冲区的指针
用于让父进程等待子进程结束的系统调用
xargs的作用是读取标准输入,将其作为后面命令的参数
1 | echo hello |xargs echo bye |
上述命令的输出为bye hello
进入insert模式
1 | i: 在光标的位置插入 |
在insert模式下
1 | ctrl + h: 删除光标前面的字符 |
在normal模式下
1 | w: 移动到下一个单词的开头 |
1 | gt:在vim不同标签之间切换 |