算法笔记

算法入门

sort

基础

  • 依赖
#include 
using namespace std;
  • 使用格式:
    sort(元素首地址(必填),元素首地址(必填),比较函数(非必填))
    默认排序是从小到大

比较函数cmp

示例代码

bool cmp(int a,int b){
    return a>b;
}

记忆:升序:a < b 左小右大;降序:b < a 左大右小

注意
sort(a,a+10,cmp);中的比较函数不能带括号

  • 案例代码:
#include 
#include 
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
#include 
#include 

using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    vector 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为整数,常用的散列函数:

  1. 直接定址法
    恒等变换:H(key)=key;
    线性变换:H(key)=a*key+b;

  2. 平方取中法
    取key的平方的中间的若干位作为hash值(很少用)

  3. 除留余数法
    把key除以一个mod,得到的余数作为hash值的方法。
    H(key)=key%mod
    表长必须不小于mod,入则可能会越界

  • 冲突避免
  1. 线性探查法
    可能两个不同的key通过H(key)函数的值相同,查找下一个位置H(key)+1。如果还存在值,继续+1探测下去,直到探测到空位置。缺点:容易扎堆

  2. 平方探测
    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大于表长,再对表长进行取模。

  3. 链地址法
    把H(key)相同的key连接成一条单链表。

字符串hash初步

  • 二维整点
    将二维整点P的坐标映射为一个整数,使得整点P可以由该整数唯一代表。(p的坐标(x,y),$ 0 \leq x,y \leq Range$)。
    H§=x*Range + y

  • 字符串

  1. 假设字符串均由大写字母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;
}
  1. 如果字符串中出现了小写字母,可以将AZ看作0-25;az看作26-51,即52进制。
  2. 如果字符串中出现数字
    • 按照小写字母处理方式,增加进制为62
    • 如果能保证字符串的末尾是确定个数的数字,可以将英文部分转换成整数,再将数字部分直接添加在后面:“BCD4”,“BCD”=731,所以BCD4=7314

你可能感兴趣的:(算法,算法笔记)