菜鸟新人所作,只为方便自己回忆,如有错误,欢迎斧正!
算法
1动态规划:最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的。子问题重叠性质:对每一个子问题只计算一次,然后将其计算结果保存在一个表格中。无后效性:以前的各阶段状态不影响未来决策。背包动态规划复杂度为O(nc)当容量c很大时不用动态规划
1 2
C语言
一 概念
1 *和& eg:int a = 10; int *b = &a;
a表示a对应的存储单元中的数据。
&a表示a对应的存储单元的地址。
*b表示:先要求b存储的是存储单元a的地址。 *b表示a存储单元中的数据
附:数组本质上其实也是指针,即:*a 等同于 a[]
函数返回数组可 设函数类型为int* fun(){ int r[] ; return r ;}
附:const int * ptr与int const * ptr完全等价,指向整型常量的整型指针ptr
int * const ptr声明了一个指向整型变量的常指针ptr
例:int a[5]={1,2,3,4,5}; int *ptr=(int*)(&a+1); printf("%d,%d",*(a+1),*(ptr-1));
答案2,5。 &a+1不是首地址+1,系统会认为加一个a数组的偏移,ptr=&(a[5])
2 字符串:C 语言中,字符串是使用 null 字符 '\0' 终止的一维字符数组
C++ 字符串除字符数组还可用string类
printf输出用%s 输出会逐个扫描字符,直到遇见 '\0' 才结束输出
字符串给字符数组赋值时自动添加 '\0',数组长度要比字符串长度大1 (字符串长度不包括 '\0')
附: 1)使用字符数组时的库函数(C:#include <string.h> C++: #include <cstring>):
复制s2到s1: strcpy(s1, s2); 连接s2到s1: strcat(s1, s2); 长度: strlen(s1);
返回int型 s1-s2: strcmp(s1, s2); 返回指针 s1中第一次位置: strchr(s1, ch);
返回指针 s1中s2第一次出现位置: strstr(s1, s2);
- C++的string类 #include <string>:复制用= ;连接用+ ;长度用.size();
3 结构体:成员访问运算符(.)
如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明
附:
4 typedef是在基本类型的基础上定义类型的同义字eg:typedef int a //a等同int
struct前加typedef 则最后的结构体变量名变为结构体类型名
typedef 仅限于为类型定义,#define定义类型或数值 eg:#define N 1;
typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。
5 共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。
共用体定义和 结构体类似,访问用 ( . )
6 1) 定义枚举 enum类型: 默认第一个元素为0,后续元素为前元素加一
Eg:enum season {spring, summer=3, autumn, winter}; 则:spring=0,autumn=4
- 定义枚举变量:enum DAY day; 或类型变量同时定义enum DAY{...} day;
- 枚举类型连续才能遍历:eg:enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } day;
for (day = MON; day <= SUN; day++) { printf("%d ", day); } 输出1234567
7 1) static全局变量与普通的全局变量: 全局变量本身就是静态存储方式,当源程序由多个源文件组成,非静态全局变量在各个源文件中都有效。静态全局变量只在定义该变量的本源文件内有效。static全局变量只能初使化一次。总之改变作用域,生存期不变。
2) 静态局部变量将生存期变为整个源程序(以前退出函数消失),作用域不变
3) static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
4) 局部变量在栈中,全局变量在静态区 中,动态申请数据在堆中。
10 "位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域 的位数 定义和结构体相仿,成员:类型 位域名: 位域长度 (用./->访问)
11 算法更优:用>>和<<代替/和* ;用&7代替%8
12 中断服务子程序(ISR)
- ISR没有参数和返回值 2) 尽量不要使用浮点数处理程序
13 预编译:展开宏定义,删除注释,处理#include预编译指令,处理条件编译指令 如#id #ifdef,添加行号和文件名标识
编译:进行词法分析、语法分析、语义分析及优化后,生成汇编代码文件
汇编:将汇编代码转变成机器可以执行的指令(机器码文件)。
链接:将各个模块之间相互引用的部分正确的衔接起来。包括了地址和空间 分配、符号决议和重定向
14 C/C++内存模型:
15内存管理:
内存管理MMU的作用:内存分配和回收,内存保护和扩充,地址映射
- void *calloc(int num, int size);动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0;共分配了 num*size 个字节长度的内存
- void free(void *address); //释放内存
- void *malloc(int num); //在堆申请指定大小内存eg:d= (char*)malloc(sizeof(char));
- void *realloc(void *address, int newsize); //内存重分配
二 编码
注:vc编码快捷键:
1)注释:先CTRL+K+C ; 取消注释:先CTRL+K+U
1, Q:黑框一闪而过
A: 开头 #include<stdlib.h> return前加 system("pause");
Q: vs报错:转换到COFF期间失败
A:项目属性-清单工具-输入输出-嵌入清单(是改否)
2 Q: continue与 break用法
A: continue结束本次循环,跳过后面语句进入下一次循环,用于(while,do,for)
Break循环结束
3 预处理命令必须以#开头 无分号包括:宏定义,文件包含,条件编译
(程序处理顺序:预处理,编译汇编,连接)
4 字符串输入输出函数 gets() <可空格不可回车> puts()<可空格不可空字符>
Eg: char str[1000]; gets(str);(gets()将回车'\n'作为输入字符数组)
附:scanf("%s", string);(不录空格 且空格或回车'\n'仍在缓存区)
printf(“%s”,str)和puts(str)均是输出到'\0'结束,遇到空格不停,但puts(str) 会在结尾输出'\n',printf(“%s”,str)不会换行
字符输入输出函数<一个字符> c=getchar() putchar(c)
5 Q:输入int型 跳行<字符串用gets>
A: int ch;
do {
scanf("%d",&data[i]);
i++;
}while((ch=getchar())!='\n');
注:输入多行数据:while(scanf("%d",&n)!= EOF){...}
6分割://char *strtok(char *s1, const char *s2)
//该函数作用是提取以s2为分隔符的字符串,并s2替换为‘\0’
//规定进行子调用时(即分割s1的第二、三及后续子串)第一参 数必须是NULL
//在每一次匹配成功后,将s1中分割出的子串位置替换为NULL(摘 下链中第一个环),因此s1被破坏了
//函数会记忆指针位置以供下一次调用,当查找不到s2中的字符时, 返回NULL
char *p;
p=strtok(tmp,",");
while(p)
{
strcpy(s[i],p); //复制字符串
i++;
p=strtok(NULL,",");
}
比较字符串返回int型eg:strcmp(s[k],s[k+1]) if(strcmp(s[k],s[k+1])>0)
6 Q:浮点型scanf("%lf%lf",&a,&b); printf("%lf %lf\n",a,b); 换成%f不行
A:用double定义a 则用%lf ; flout型 的可以用%f,也可以用%lf
7 Q:字符串数组长度 <sizeof是内存不是元素个数>
A:#include<string.h> char input[10000]; length = strlen(input);
8 时间之差用时分秒换算成秒再取模 eg: minute = sum%3600/60
second = sum%3600%60
9 结构体 typedef struct{
...}time; time result; result.* ==... <*代表结构体中元素>
12代码细节
- char * const p; //常量指针,p值不可改; char const * p;//指向常量的指针
13 c语言有符号数和无符号数进行比较运算时(==,<,>,<=,>=),有符号数隐式转换成了无符号数。 eg:int a=-14; a>6; -14的补码为1111111111110010。此数进行比较运算时,被当成了无符号数,它远远大于6
14 、库函数
14.1 库函数<stdlib.h>
1) 字符串转浮点型:double atof(const char *str)
2) 字符串转int型:int atoi(const char *str)
14.2 库函数<string.h>
1)复制s2到s1: strcpy(s1, s2); 2)连接s2到s1: strcat(s1, s2); 3)长度: strlen(s1);
4)返回int型s1-s2: strcmp(s1, s2); 5)返回指针s1中第一次位置: strchr(s1, ch);
6)返回指针 s1中s2第一次出现位置: strstr(s1, s2);
7)用分隔符(s2)分隔s1成多个字符串 char *strtok(char *s1, const char *s2)
注:每次返回第一个子串的指针,从第二次调用strtok()将参数s1设置成 NULL。每次调用成功则返回指向被分割出片段的指针。
Eg:char dest[]="ab,cd,ef,c"; char* rp; char ch[]= ","; rp=strtok(dest, ch);
while(NULL != rp) { printf("dest: %s ", dest);
printf("rp: %s \n", rp); rp=strtok(NULL, ch); }
8) void *memcpy(void*str1,const void*str2 ,size_t n) //str2的n个字符复制到str1
eg∶ memcpy(d, s+11,6);//从第11个字符(r)开始复制,连续复制6个字符(runoob)
9) char*strcat(char*dest,const char*src) // src所指字符串追加到dest末尾
char*strncat(char*dest, const char*src,size_t n)//追加结尾,直到n字符长度
10) 返回字符串中字符的位置-strchr 返回包括第一个字符和之后的字符串;用数组相减就行 eg∶
char*p; p= strchr(arr,'g’); printf("%d",p-arr);
11) 返回字符串中字符串的位置-strstr返回包括第一个字符和之后的字符串;用数组相减就行 eg:
char *p; p= strstr(arr,”g”); printf("%d",p-arr);
12) 比较字符串返回 int型eg: strcmp(s[k],s[k+1]) if(strcmp(s[k],s[k+1])>0)
(附: A是65,a是97,差32)
14.3库函数<ctype.h>
int isalpha(int c) //判断是否为字母,是字母返回非0 int型
int tolower(int c); //字母转小写字母,eg: tolower(str[i])
int toupper(int c); //字母转大写字母
- 常用场景
15.1-15.5 dp、贪心、分治、回溯、dfs、bfs、
1) 动态规划:最优子结构性质:如果问题的最优解所包含的子问题的解也是最优的。子问题重叠性质:对每一个子问题只计算一次,然后将其计算结果保存在一个表格中。无后效性:以前的各阶段状态不影响未来决策。背包动态规划复杂度为O(nc)当容量c很大时不用动态规划。
2) 贪心算法:每一步都是当前最优解,局部最优选择,并且最终能够求得问题的整体最优解。这些子问题之间没有关联且独立的(动态规划子问题有关联)。
3) 分治:难的大问题可以分为若干规模小的相同且独立的子问题,利用子问题的解,可以合并成该问题的解。如归并排序。
4) 回溯法是对解空间的深度优先搜索。Eg:
void backtracking(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
}
}
附:法1:回溯dfs输出子集-输出无条件
vector<vector<int>>res;
void dfs(vector<int>nums,vector<int>&path,int start)
{
res.push_back(path);
for(int i=start; i<nums.size(); i++)
{
path.push_back(nums[i]);//做出选择
dfs(nums,path,i+1);//递归进下一层,i+1标识下一个开始位置
path.pop_back();//撤销选择
}
}
法二:递归输出子集-无for循环
vector<int> t; //存子集
void dfs(int cur, int n) {
if (cur == n) {
// 记录答案
return;
}
// 考虑选择当前位置
t.push_back(cur);
dfs(cur + 1, n, k);
t.pop_back();
// 考虑不选择当前位置
dfs(cur + 1, n, k);
}
5) Dfs :递归或栈,与树有关
6) Bfs:队列
8) 树的层次遍历(知每一层)
vector<vector<int>> levelOrder(TreeNode* root) {
/* 根据函数返回值定义存储结果的变量 */
vector<vector<int>> result;
queue<TreeNode*> que;
if(root != NULL) que.push(root);
while(!que.empty()) {
/* 计算队列的大小也即有多少个孩子 */
int size = que.size();
/* 定义一个临时vector 存储每一层 */
vector<int> vec;
for(int i = 0; i < size; i++) { //遍历每一层
TreeNode* node = que.front(); //获取第一个节点数据
que.pop();
vec.push_back(node->val);
if(node->left != NULL) que.push(node->left);
if(node->right != NULL) que.push(node->right);
}
result.push_back(vec); // /* 将一层的数据保存 */
}
return result;
}
10) 辗转相除法求公因数∶
int gcd(int a,int b) { //辗转相除法
if(a%b==0)
return b;
return gcd(b,a%b);
}
11) 字符串反串∶
#include(algorithm>
string str; cin >> str;
reverse(str.begin(),str.end());
12) 找素数思路
a) 素数的倍数排除素数
b) 素数一定是6的倍数加减一,代码如下∶
int prime(int num) {
if (num <= 3){
return 1;
}
// 不在6的倍数两侧的一定不是质数
if (num %6!=1&& num %6!= 5{
return 0;
}
int s = sqrt(num); //sqrt可以对int和double开根返回double
//int s= sqr(num, 0, num);
for (int i= 5; i<=s; i+=6) {
if (num%i==0 || num %(i+2)== 0){
return 0;
}
}
return 1;
}
16 1)文件打开 FILE *fopen( const char * filename, mode );//字符串目录和模式
mode: r//只读; w//只写,不存在则新建; a//追加模式写; (有+则允许读写)
Eg:FILE *fp = NULL; fp = fopen("/tmp/test.txt", "w+");
- 文件关闭fclose(文件名);
- 写入文件:int fputs( const char *s, FILE *fp );把字符串s写入,成功返回正 数;失败返回EOF
附: int fprintf(FILE *fp,const char *format) 写入字符串
- 读取文件:char *fgets( char *buf, int n, FILE *fp );读取 n - 1 个字符并在最后追加一个 null 字符来终止字符串;读取时遇到换行符 '\n' 或文件末尾 EOF,则只会返回读取到的字符,包括换行符
附:fscanf(FILE *fp, const char *format, 串名) 读取字符串,遇到空格和换行符停止读取。 eg: fscanf(fp, "%s", buff);
- 二进制文件读取用:fread和fwrite
17错误处理:C提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。
18内存管理:
内存管理MMU的作用:内存分配和回收,内存保护和扩充,地址映射
- void *calloc(int num, int size);动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0;共分配了 num*size 个字节长度的内存
- void free(void *address); //释放内存
- void *malloc(int num); //在堆申请指定大小内存eg:d= (char*)malloc(sizeof(char));
- void *realloc(void *address, int newsize); //内存重分配