zoukankan      html  css  js  c++  java
  • 算法笔记(常用数据结构)

    1.时间处理

    PAT中有些问题把时间转换为以 s 为单位可以简化很多操作。

    scanf("%d:%d:%d", &hh, &mm, &ss); //输入格式
    int timeToInt(int hh, int mm, int ss){
        return hh * 3600 + mm * 60 + ss;
    }
    printf("%02d:%02d:%02d
    ", sumTime/3600, sumTime%3600/60, sumTime%60);  //输出转换为输入形式

    2.日期处理

    int month[13][2] = {//平年和闰年的每个月的天数
      {0, 0}, {31, 31}, {28, 29}, {31, 31}, {30,30}, {31, 31}, {30,30}, {31, 31}, {31, 31}, {30,30}, 
      {31, 31}, {30,30}, {31, 31}
    }
    bool isLeap(int year){ //判断是否是闰年
      return (year%4==0 && year%100!=0) || (year%400 == 0);
    }

    3.进制转换

    //将P进制数x转换为十进制数y
    int y = 0, product = 1;  //product在循环中会不断乘P,得到 1、P、P^2、P^3....
    while (x != 0){
      y = y + (x%10) * product;  // x%10 是为了每次获取x的个位数
      x = x / 10;     // 去掉x的个位
      product = product * P;   
    }
    
    //将十进制数y转换为Q进制数z,采用  (除基取余倒排法)
    int z[40], num = 0;   //数组z存放Q进制数y的每一位,num为位数
    do{
      z[num++] = y % Q;  //除基取余
      y = y / Q;
    } while(y != 0);   //当商不为0时进行循环

    4.最大公约数、最小公倍数

    int gcd(int a, int b){  //最大公约数
        if(b == 0) return a;
        if(a < b) return gcd(b, a);
        else return gcd(b, a%b);
    }
    int lcm = (int a, int b){  //最小公倍数
        return a*b/gcd(a, b);  //a,b的最小公倍数为a*b/最大公约数
        //考虑a*b可能溢出,可写为 a/d*b
    }

    5.分数的输入形式

    struct Fraction{
        long long up, down;  //分子、分母
    } result;
    scanf("%lld/%lld", &result.up, &result.down);
    //分数化简
    Fraction reduction(Fraction result){
        if(result.down < 0){ //分母为负数,令分子分母都变为相反数
            result.up = -result.up;
            result.down = -result.down;
        }
        if(result.up == 0){ //如果分子为0,则令分母为1
            result.down = 1;
        }else{//如果分子不为0,则进行约分
            int d = gcd(abs(result.up), abs(result.down));  //分子分母的最大公约数
            result.up /= d;
            result.down /= d;
        }
    }
    //分数的加减乘除

    6.判断是否为素数(Prime)

    N不会被除自己以外的大于根号N的整数整除(减少运算复杂度)

    bool isPrime(int n){ //判断n是否为素数
        if(n <= 1) return false;  //1即不为素数,也不为合数
        int sqr = (int)sqrt(1.0*n);
        for(int i=2; i<=sqr; i++){
            if(n%i == 0) return false;
        }
        return true;
    }

    7.C++ sort()排序函数

    #include <algorithm>
    sort( 首元素地址(必填), 尾元素地址的下一个地址(必填), cmp 比较函数(非必填) );
    //比较函数不填则默认对前面给出的区间进行递增排序
    //提供 cmp 函数实现排序规则
    bool cmp(Student a, Student b){
      int s = strcmp(a.name, b.name);
        if(s != 0) return s < 0;  //按姓名字典序从小到大排序
        else return a.id < b.id;
    }

    8.字符串Hash

    符串hash是指将一个字符串映射成为一个整数,使得该整数可以尽可能唯一地代表字符串S。

    //A student name consist of 3 capital(大写) English letters plus a one-digit number
    const int M = 26*26*26*10+1;
    vector<int> vec[M];
    int getID(char name[]){
        int id = 0;
        for(int i=0; i<3; i++){
            id = id * 26 + (name[i] - 'A');
        }
        id = id * 10 + (name[3] - '0');
        return id;
    }

    9.插入排序

    void insertDort(int arr[], int n){//升序
        for(int i=1; i<n; i++){
            int temp = arr[i], j=i;
            while(j >0 && arr[i-1] > temp){
                arr[j] = arr[j-1];
                j--;
            }
            arr[j] = temp;
        }
    }
    //简便方法,使用sort函数
    void insertDort(int arr[], int n){//升序
        for(int i=1; i<n; i++){
            sort(arr, arr+i+1); //*****
        }
    }

    10.归并排序

    void mergeSort(int arr[], int n){
        for(int step = 2; step/2 <=n; step *= 2){
            for(int i=0; i<n; i+=step){
                sort(arr+i, arr+min(i+step, n));  //使用sort函数的技巧
            }
        }
    }

    11.二分查找

    //前提是数组有序
    int binarySearch(int arr[], int left, int right, int x){
        int mid;
        while(left <= right){
            mid = (left + right) / 2;
            if(arr[mid] = x)  return mid;  //找到解,返回mid
            else if(arr[mid] < x) left = mid + 1;
            else right = mid -1;
        }
        return -1;  //解不存在
    }
    //在a[i+1]~a[n-1]中查找第一个超过a[i]*p的数,返回其位置给j
    int j = upper_bound(arr+i+1, arr+n, (long long)arr[i]*p) - arr;
    //在a[i+1]~a[n-1]中查找第一个大于或等于a[i]*p的数,返回其位置给j
    int j = upper_bound(arr+i+1, arr+n, (long long)arr[i]*p) - arr;

    12.数组中两个数据交换使用 swap()函数

    swap(arr[1], arr[2]);

    13.常用定义静态链表的格式

    struct Node{
        int address; //结点地址
        int data;  //数据域
        int next; //指针域
        int order; //结点在链表上的序号
        XXX;  //
    } node[100]; //结点的某个性质,不同的题目会有不同的设置

    14.质因子分解

    //对一个整数n来说,如果它存在[2,n]范围内的质因子,要么这些质因子全部小于等于 sqrt(n),要么只存在一个大于sqrt(n)的质因子,而其余质因子全部小于等于sqrt(n)
    struct factor{
        int x, cnt;  //x为质因子,cnt为其个数
    }fac[10];
    if(n%prime[i]==0){ //prime为质数表,如果prime[i]是n的因子
        fac[num].x = prime[i]; //记录该因子
        fac[num].cnt = 0;
        while(n%prime[i] == 0){  //计算出质因子prime[i]的个数
            fac[num].cnt++;
            n /= prime[i];
        }
        num++;  //不同质因子个数加 1
    }
    if(n!=1){  //如果无法被根号n以内的质因子除尽
        fac[num].x = n;  //那么一定有一个大于根号n的质因子
        fac[num++].cnt = 1;
    }

    15.计算n!中有多少个质因子p

    int cal(int n, int p){
        int ans = 0;
        while(n){
            ans += n/p;  //累加n/p^k
            n /= p;    //相当于分母多乘一个p
        }
        return ans;
    }
  • 相关阅读:
    JS如何判断是否已经引入某个css或是js?
    FILTER:progid:DXImageTransform.Microsoft.Gradient使用
    根据ip查询ip归属地
    java判断是否是合法IP
    jQuery下实现等待指定元素加载完毕(可改成纯js版)
    jsp 循环数字
    jsp获取当前日期
    MyBatis In的使用
    给半径求圆面积
    实现一个数值加法函数,返回两个数字的和。要求能进行参数验证,若参数不是数字或为空则抛出异常。
  • 原文地址:https://www.cnblogs.com/dear_diary/p/8616248.html
Copyright © 2011-2022 走看看