算法入门
sort
基础
- 依赖
#include <algorithm>
using namespace std;
- 使用格式:
sort(元素首地址(必填),元素首地址(必填),比较函数(非必填))
默认排序是从小到大
比较函数cmp
示例代码
bool cmp(int a,int b){
return a>b;
}
记忆:升序:a < b 左小右大;降序:b < a 左大右小
注意
sort(a,a+10,cmp);中的比较函数不能带括号
- 案例代码:
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main()
{
int a[10]={1,3,5,6,3,2,8,9,0,7};
sort(a,a+10,cmp);
for(int i=0;i<10;i++){
cout << a[i] << " ";
}
return 0;
}
容器排序
在STL标准容器中,只有vector、string、deque可以使用sort。像set、map这种容器是使用红黑树实现的,元素本身有序,所以不能使用sort排序。
这里以vector为例:
#include<cstdio>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main(){
vector<int> vi;
vi.push_back(3);
vi.push_back(1);
vi.push_back(2);
sort(vi.begin(),vi.end(),cmp);
for(int i=0;i<3;i++){
printf("%d ",vi[i]);
}
return 0;
}
排名实现
排名一般规则:分数不同排名不同,分数相同排名相同。
例如5个学生的分数:90、88、88、88、86
对应名次:1、2、2、2、5
学生结构体Student
struct Student{
char name[10];//姓名
int score;//分数
int r;//排名
}stu[10010];
- 存储方式
先将数组的第一个学生的排名标记为1,然后遍历所有学生,如果当前学生的分数等于上一个学生的分数,排名和上一个学生相同。如果不同,排名为数组下标+1。并保存到结构体中
stu[0].score=1;
for(int i=1;i< n;i++){
if(stu[i].score==stu[i-1].score){
stu[i].r=stu[i-1].r;
}else{
stu[i].r=i+1;
}
}
- 直接输出
很多时候排名信息不需要保存,只是一次输出即可。思路和上面类似,定义一个整数r=1,遍历学生数组,如果当前学生的分数等于上一个学生的分数,排名和上一个学生相同。如果不同,排名为数组下标+1。
int r=1;
for(int i=0;i< n;i++){
if(i!=0&&stu[i].score!=stu[i-1].score){
r=i+1;
}
printf("%d",r );
}
散列
知识点
散列浓缩定义:将元素通过一个函数转换为整数,使得改整数可以尽量唯一的代表这个元素。这个转换函数成为散列函数H。元素在转换前为key,转换后为H(key)
如果key为整数,常用的散列函数:
-
直接定址法
恒等变换:H(key)=key;
线性变换:H(key)=a*key+b; -
平方取中法
取key的平方的中间的若干位作为hash值(很少用) -
除留余数法
把key除以一个mod,得到的余数作为hash值的方法。
H(key)=key%mod
表长必须不小于mod,入则可能会越界
- 冲突避免
-
线性探查法
可能两个不同的key通过H(key)函数的值相同,查找下一个位置H(key)+1。如果还存在值,继续+1探测下去,直到探测到空位置。缺点:容易扎堆 -
平方探测
H ( k e y ) + 1 2 H(key)+1^{2} H(key)+12、 H ( k e y ) − 1 2 H(key)-1^{2} H(key)−12、 H ( k e y ) + 2 2 H(key)+2^{2} H(key)+22、 H ( k e y ) − 2 2 H(key)-2^{2} H(key)−22、……一般为了进行正向的平方探查。如果 H ( k e y ) + k 2 H(key)+k^{2} H(key)+k2大于表长,再对表长进行取模。 -
链地址法
把H(key)相同的key连接成一条单链表。
字符串hash初步
-
二维整点
将二维整点P的坐标映射为一个整数,使得整点P可以由该整数唯一代表。(p的坐标(x,y),$ 0 \leq x,y \leq Range$)。
H§=x*Range + y -
字符串
- 假设字符串均由大写字母AZ组成,把AZ看作0~25,即26进制。
int hashFunc(char S[],int len){
int d=0;
for(int i=0;i< len;i++){
id=id*26+(S[i]-'A');
}
return id;
}
- 如果字符串中出现了小写字母,可以将AZ看作0-25;az看作26-51,即52进制。
- 如果字符串中出现数字
- 按照小写字母处理方式,增加进制为62
- 如果能保证字符串的末尾是确定个数的数字,可以将英文部分转换成整数,再将数字部分直接添加在后面:“BCD4”,“BCD”=731,所以BCD4=7314