【机试】计算机考研复试常用必备知识点

一.常用基础知识

1.常用数据范围

int :10位 【-231—231-1】
long long:19位 【-263—263-1】
四舍五入取整
简易方法:(int)(a+0.5)

2.进制转换

(1)十进制转换为d进制数

  //sum:十进制数 d:d进制数
  int ans[40], num = 0;
  //将十进制数sum转化为d进制,结果存放于数组ans,num表示位数
  //ans数组中存放的数字为反序,要倒着输出
  do{
    ans[num++] = sum % d; //除基取余
    sum /= d;    
  }while(sum != 0);

(2)d进制数转换为十进制数

  int y=0,temp=1;
  while(x!=0){
     y+=(x%10)*temp;
     x/=10;
     temp*=d;
  }

若输出格式中包含ABCD…,可以先定义一个char数组存放字符

char temp[13]={'0','1','2','3','4','5','6','7','8','9','A','B','C'};

扩展
输入字符串形式的数字,将其转换成十进制整数

string s;
getline(cin,s);
int temp=0;
for(int i=0;i<s.size();i++){
    temp=temp*10+(s[i]-'0');
}

3.scanf函数与getline函数

scanf函数:读入字符数组时,必须读入字符才算作读入,空格、换行符都不会读入
注意区分scanf("%d %c")scanf("%d%d")
前者在输入字符的时候要特别注意,后者一般用在输入数字

getline函数:会读入一行,不管是空还是有字符
常见用法:

//char数组实现输入字符串
char str[100];
cin.getline(str,100);
//string实现输入字符串
string str;
getline(cin,str);

重点:
(1) 输入字符串尽量使用getline函数,PAT中无法使用gets函数
因此我们在使用时一定要注意,如果有空字符会读入,一定要使用getline
(2) getline函数之前包括其他输入时,先清空输入流

int n;
string str;
cin>>n;
cin.ignore();
getline(cin,str);

4.赋值函数

memset函数 必须加string.h的头文件

memset(a,0,sizeof(a));

fill函数 必须加algorithm的头文件

fill(a,a+n,0);

5.字典序问题

涉及字符串比较时间大小比较,且数据量小的时候,可采用字符串string的字典序直接比较。
注意使用string类型时,必须加#include <string>的头文件
补充重点
字符串比较函数strcmp(,),比较原则依然是字典序

strcmp(str1,str2);

返回值为负整数(str1<str2)、0(str1=str2)、正整数(str1>str2)
数据量大的时候,可以使用二维char数组直接比较字典序(A1047)

6.各种头文件对应方法

<math.h>
fabs(double x):(浮点数)取绝对值
floor(double x):向下取整
ceil(double x):向上取整
sqrt(double x):算术平方根
round(double x):四舍五入

<algorithm>
max(x,y) / min(x,y):最大值 / 最小值
abs(int x):(整数)取绝对值
swap():交换
reverse():逆转
sort():排序

7.溢出判断

若a,b均为int型变量,(31位)
a>0,b>0,a+b<0 发生正溢出
a<0,b<0.a+b>0 发生负溢出

8.最后一位不能有空格

若输出数组,且最后一个数后不能输出空格,应先用循环输出前n-1个数,最后单独输出最后一个数,或者用辅助数据temp计数判断输出。

9.卡特兰数

用于计算给定n个结点,求二叉树的形态数
在这里插入图片描述

二.字符串问题

1.字符串hash

将字符串转换成数字(A1039)

int getid(char a[]){
	int sum=0;
	for(int i=0;i<3;i++){
	    sum=sum*26+(a[i]-'A');
	}
	sum=sum*10+(a[3]-'0');
	return sum;
}

2.字符串长度问题

C语言:

#include <string.h>
#include <stdio.h>
char str[100];
gets(str);        //尽量不使用gets函数输入字符串
int len=strlen(str);

C++:

#include <iostream>
#include <string>
using namespace std;
string str;
cin>>str;
int len=str.length();

3.字符串string常用函数

auto关键字:自动推断变量类型,可用于表示地址变量
举例
isdigit()方法:用来判断是否为数字

char str[100];
string n="abc123";
for(auto it=n.begin();it!=n.end();it++){
    int k=isdigit(*it)?*it-'0':*it-'0'+10;
}
//注意it属于地址变量,若取对应位置字符时,应采用指针表示

max_element()方法:返回最大值的第一个位置

char m=*max_element(n2.begin(),n2.end());

4.字符串输入注意问题

(1)若题目要求先输入n,再输入n个字符串,注意在输入n后吸收回车符

getchar();                     //吸收空格

(2)字符串输入一般使用getline

三.动态规划

1.最大连续子序列和

dp数组:dp[i]表示以A[i]为末尾的连续序列的最大和(A[i]必须为末尾)
状态转移方程:

dp[i] = max(A[i],dp[i-1]+A[i]);

2.最长不下降子序列(LIS)

dp数组:dp[i]表示以A[i]为末尾的最长不下降子序列的长度(A[i]必须为末尾)
状态转移方程:

dp[i] = max(1,dp[j]+1);

3.最长公共子序列(LCS)

dp数组:dp[i][j]表示字符串A的i号位和字符串B的j号位之前的LCS长度(下标从1开始)
状态转移方程:

dp[i][j]=dp[i-1][j-1]+1;                A[i]==B[j]
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);    A[i]!=B[j]

4.注意事项

(1)dp数组以及目标数组定义在main函数外
(2)LCS输入字符串时,由于下标应从1开始,因此输入格式如下:

char a[100];
cin>>(a+1); 或者   gets(a+1);

四.数学问题

1.素数问题

判断一个数是否为素数

bool isPrime(int n){
    if(n<=1)
        return false;
    for(int i=2;i*i<=n;i++){
        if(n%i==0)
            return false;
    }
    return true;
}

2.二分查找

upper_bound(first,last,val):返回第一个大于val的元素位置

int upper_bound(int A[],int left,int right,int x){
    while(left<right){
        int mid=(left+right)/2;
        if(A[mid]>x){     //区别点
            right=mid;
        }else{
            left=mid+1;
        }
    }
    return left;
}

lower_bound(first,last,val):返回第一个大于等于val的元素位置

int lower_bound(int A[],int left,int right,int x){
    while(left<right){
        int mid=(left+right)/2;
        if(A[mid]>=x){    //区别点
            right=mid;
        }else{
            left=mid+1;
        }
    }
    return left;
}

五.排序问题

插入排序与归并排序(A1089)
插入排序与堆排序(A1098)
Tip:堆排序由于使用2i或2i+1表示左右子树,所以for循环应该从1开始,而不是从0开始

1.sort比较的cmp函数

整数比较:

//从大到小
bool cmp(int a,int b){
     return  a>b;
}

结构体的比较:

//先按x属性从小到大,再按y属性从小到大
bool cmp(Student a,Student b){
     if(a.x!=b.x)
         return a.x<b.x;
     return a.y<b.y;
}

注意点:排序问题中的计算同分排名时,参考A1025的做法

    int r=1;
	sort(s,s+num,cmp);
	for(int i=0;i<num;i++){
		if(i>0&&s[i].score!=s[i-1].score)
			r=i+1;
		printf("%s %d",s[i].id,r);
	
	}

六.C++模板库

1.vector变长数组

若输入n个数且要定义一个n个大小的数组,可采取vector数组的resize方法

#include <iostream>
#include <vector>
using namespace std;
vector<int> v;
int n;
cin>>n;
v.resize(n);

2.Map数组常见问题

若采用空间换时间的辅助数组,注意辅助数组的大小不能过大,否则容易产生段错误
解决办法:使用map数组

3.优先队列(priority_queue)

priority_queue<int> q;
priority_queue<int,vector<int>,less<int>> q;     优先级从大到小
priority_queue<int,vector<int>,greater<int>> q;  优先级从小到大

4.栈的应用(后缀序列求值)

思路:输入一个字符串,如果输入的元素为数字,则入栈,如果输入的元素是运算符,则出栈两个元素s1,s2,将s2运算符s1的结果入栈,最终输出栈顶元素,则为最终求得的结果。

#include <iostream>
#include <stack>
#include <string>
using namespace std;
stack<int> s;
int main(){
	string str;
	cin>>str;
	int k;
	for(int i=0;i<str.size();i++){
		if(str[i]>='0'&&str[i]<='9'){
		   int temp=str[i]-'0';
		   s.push(temp);
		}else if(str[i]=='+'){
			int a=s.top();
			s.pop();
			int b=s.top();
			s.pop();
            k=b+a;
			s.push(k);
		}else if(str[i]=='-'){
		    int a=s.top();
			s.pop();
			int b=s.top();
			s.pop();
            k=b-a;
			s.push(k);
		}
	}
	cout<<s.top()<<endl;
    return 0;
}

七.数据结构

1.静态链表做题思路

1.结构体定义

struct Node{
    int address;
    typename data;
    int next;
    xxx;                //根据题目要求确定
}node[maxn];

2.静态链表初始化

for(int i=0;i<maxn;i++){
    node[i].xxx=0;
}

3.串联链表
法一:一次scanf

for(int i=0;i<n;i++){
    scanf("%d %c %d",&address,&data,&next);
    node[address].data=data;
    node[address].next=next;
}

法二:两次scanf

for(int i=0;i<n;i++){
    scanf("%d",&address);
    scanf("%d%d",&node[address].data,&node[address].next);
    node[address].address=address;
}

4.遍历链表

int s;
for(int p=s;p!=-1;p=node[p].next){
    node[p].xxx;
}

Tip:
1.结构体定义的变量可以和main函数定义的变量名相同
2.注意地址的输出可以采用“%05d

2.二叉树遍历

先序遍历/中序遍历/后序遍历
注意:先写递归边界

if(root=NULL){
    return;
}

层序遍历(队列实现)

struct node{
    int data;
    node* lchild;
    node* rchild;
    int layer;                   //记录二叉树所在层数
}
int num=0;
void LayerOrder(node* root){
    queue<node*> q;
    root->layer=1;
    q.push(root);
    while(!q.empty()){
        node* now=q.front();
        q.pop();
        printf("%d",now->data);
        num++;
        if(num<n)
            printf(" ");
        if(now->lchild!=NULL){
            now->lchild->layer=now->layer+1;
            q.push(now->lchild);
        }
        if(now->rchild!=NULL){
            now->rchild->layer=now->layer+1;
            q.push(now->rchild);
        }
    }
}

Tip:如果最后输出最后一个数不能为空格,可以设置一个标记数num记录,在递归左右子树之前加一个判断语句

3.DFS与BFS

DFS:系统栈实现
BFS:队列实现
重点例题:A1004

4.BST(二叉查找树)

插入操作

void insert(node* &root,int data){        //BST的插入操作
	if(root==NULL){
	   root=new node;
	   root->data=data;
	   root->lchild=root->rchild=NULL;
	   return;
	}
	if(data<root->data)
		insert(root->lchild,data);
	else
		insert(root->rchild,data);
}

遍历
注意:用vector数组存储遍历序列

void preOrder(node* root,vector<int>&vi){      //先序遍历
	if(root==NULL)
		return;
	vi.push_back(root->data);
	preOrder(root->lchild,vi);
	preOrder(root->rchild,vi);
}

5.图

(1)无向图若增加边数让该无向图图连通,其中增加的边数=连通块个数-1
(2)连通块个数的求法:①图的遍历(A1013) ②并查集

6.迪杰斯特拉算法(Dijkstra)

Dijkstra完整代码:

//邻接表法
vector<int> pre[maxv];
int n,G[maxv][maxv],d[maxv];
bool vis[maxv]={false};
void Dijkstra(int s){
    fill(d,d+maxv,INF);
	d[s]=0;
	for(int i=0;i<n;i++){
	    int u=-1,min=INF;
		for(int j=0;j<n;j++){
			if(vis[j]==false&&d[j]<min){
			    u=j;
				min=d[j];
			}
		}
		if(u==-1)
			return;
		vis[u]=true;
		for(int v=0;v<n;v++){
			if(vis[v]==false&&G[u][v]!=INF){
				if(d[u]+G[u][v]<d[v]){
				    d[v]=d[u]+G[u][v];
					pre[v].clear();
					pre[v].push_back(v);  //区别点
				}else if(d[u]+G[u][v]==d[v])
					pre[v].push_back(v);
			}				
		}
	}
}

7.最短路径问题

解决方法:Dijkstra+DFS(A1030)
注意事项:
(1)递归边界

void DFS(int v){
    if(v==st){           //st为起点
        printf("%d ",v);
        return;
    }
    DFS(pre[v]);
    printf("%d ",v);    
}

(2)输入初始参数(起点,终点,权值1,权值2)

int u,v;
for(int i=0;i<n;i++){
    printf("%d%d",&u,&v);
    printf("%d%d",&G[u][v],&cost[u][v]);
}  //注意分开两个printf输入
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 数据库考研复试常考的知识点主要包括以下几个方面: 1. 数据库系统基础知识:包括数据库的概念、结构、组成部分、数据模型和数据库管理系统的基本功能。 2. 数据库设计与规范化:包括关系模型、ER模型、数据库设计的基本原则、数据规范化等。 3. SQL语言:包括SQL语言基础、数据查询语句、数据修改语句、数据控制语句等。 4. 数据库管理:包括数据库的备份与恢复、事务管理、数据库安全与权限控制等。 5. 数据库应用开发:包括基于数据库的应用程序开发、数据库编程语言、数据库连接、事务处理等。 需要注意的是,不同院校对数据库考研复试的考查内容可能会有所不同,以上仅是一些常见的考查内容,考生需要结合自己所报考的院校和专业进行有针对性的备考。 ### 回答2: 数据库考研复试常考的知识点主要包括以下几个方面。 1. 数据库基础知识:包括数据库的概念、数据库管理系统(DBMS)的基本原理和功能,数据库的组成和分类等。 2. 数据库设计:包括关系数据库的概念和特点,关系模型的基本概念和代数运算,实体-关系模型(ER模型)的基本概念和表示方法,关系数据库的设计步骤和规范等。 3. 数据库查询:包括结构化查询语言(SQL)的基本语法和常用查询语句,如SELECT、INSERT、UPDATE和DELETE等,SQL查询的基本原理和优化技巧,常用的查询操作和函数等。 4. 数据库事务和并发控制:包括事务的概念、特性和属性,事务的隔离级别和并发控制的基本原理和方法,如锁机制、并发控制算法和恢复机制等。 5. 数据库存储和索引:包括数据库存储结构和文件组织,数据存储的方法和策略,索引的概念和分类,索引的创建、使用和优化等。 6. 数据库安全和完整性:包括数据库的安全性、权限控制和用户管理,数据库的完整性约束和触发器,数据库备份和恢复等。 以上是数据库考研复试常考的知识点的一个概述,具体的考点和题型可能会因不同学校和考试而有所不同。备考时,应结合具体复试要求和题型特点进行有针对性的学习和准备。 ### 回答3: 数据库考研复试常考的知识点主要包括以下几个方面。 首先是数据库基础知识。必须熟悉关系数据库的概念和基本术语,了解数据库的组成和体系结构,知道数据库的分类和特点。还需要了解关系模型、数据模型和数据独立性等基本概念。 其次是数据库设计与规范化。需要掌握实体-关系模型的基本原理和表示方法,了解关系数据库设计的一般步骤和方法。还需要理解数据规范化的理论和方法,了解各个范式的定义和应用。 第三是SQL语言。需要熟悉SQL语言的基本语法和常用命令,包括数据查询、数据更新、数据插入、数据删除等。还需要了解SQL语言的高级特性,如连接查询、嵌套查询、聚合查询等。 第四是数据库索引和优化。需要掌握数据库索引的概念和作用,了解索引的种类和建立方法。还需要了解数据库的优化策略和优化技术,如查询优化、物理存储优化等。 最后是数据库管理与安全。需要了解数据库管理的基本任务和工作内容,掌握数据库备份和恢复的方法。还需要了解数据库的安全性和权限管理,理解用户和角色的概念,掌握用户管理和权限控制的方法。 综上所述,数据库考研复试常考的知识点涵盖了数据库基础知识、数据库设计与规范化、SQL语言、数据库索引和优化以及数据库管理与安全等方面。只有对这些知识点有全面的了解和掌握,才能在考试中取得好成绩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值