Loading

C++用法个人速记

C++常用数据类型取值范围

unsigned int 0~4294967295
int -2147483648~2147483647 10e10数量级
unsigned long 0~4294967295
long -2147483648~2147483647
long long的最大值:9223372036854775807 10e19数量级
long long的最小值:-9223372036854775808
unsigned long long的最大值:18446744073709551615 //20位

整数二分模板

1、左区间右端点

//区间分为 [l,m-1] 和 [m,r] 两个区间 
int l,r,m;
while(l<r){
    m=(l+r+1)/2; //为了避免溢出也可以写成m=l+(r+1-l)/2;
    if(target<a[m]){ //如果target落入左区间
        r=m-1;
    }
    else l=m; //如果落入右区间
}
//结束的时候l=r

2、右区间左端点

//区间分为 [l,m] 和 [m+1,r] 两个区间
int l,r,m;
while(l<r){
    m=(l+r)/2; //为了避免溢出也可以写成m=l+(r-l)/2;
    if(target>a[m]){ //如果target落入右区间
        l=m+1;
    }
    else r=m;
}
//结束的时候l=r

新的整数二分模板

int l = 0, r = n - 1;
int ans=0; //右区间左端点
while (l <= r)
{
    int mid = l + r >> 1;
    if (q[mid] >= x) //如果在右侧区间
    {
        ans = mid;
        r = mid - 1;
    }
    else l = mid + 1;
}
//结束的时候,答案是ans

KMP模板

下标从1开始(需要在字符串前面加一个空格)

//haystack为主串,needle为模式串
int strStr(string haystack, string needle) {
    int n = haystack.size(), m = needle.size();
    haystack = ' ' + haystack;
    needle = ' ' + needle; //下标均从1开始,需要在字符串前面加上一个' '
    vector<int> next(m + 1);
    for (int i = 2, j = 0; i <= m; i++) {
        while (j and needle[i] != needle[j + 1])
            j = next[j];
        if (needle[i] == needle[j + 1])
            j++;
        next[i] = j;
    }
    for (int i = 1, j = 0; i <= n; i++) {
        while (j and haystack[i] != needle[j + 1])
            j = next[j];
        if (haystack[i] == needle[j + 1])
            j++;
        if (j == m)
            return i - m; //此处如果不返回,可以输出所有符合条件的下标
    }
    return -1;
}

下标从0开始,next[0]=-1

int strStr(string haystack, string needle) {
    int n = haystack.size(), m = needle.size();
    int next[m];
    next[0] = -1; //下标从0开始,next[0]=-1
    for (int i = 1, j = -1; i < m; i++) {
        while (j >= 0 and needle[i] != needle[j + 1])
            j = next[j];
        if (needle[i] == needle[j + 1])
            j++;
        next[i] = j;
    }
  
    for (int i = 0, j = -1; i < n; i++) {
    	while (j >= 0 and haystack[i] != needle[j + 1])
            j = next[j];
        if (haystack[i] == needle[j + 1])
            j++;
        if (j == m - 1)
            return i - m + 1; //此处如果不返回,可以输出所有符合条件的下标
    }
    return -1;
}

并查集模板

int nation[N];

for(int i=0;i<n;i++) //把每个结点的父节点初始化为自己,即每个节点都是一个集合
	nation[i]=i;

void join(int i, int j) //合并两个集合
{
    int root1=find(i); //先判断两个结点是否在同一个集合
    int root2=find(j); //如果在就不用做操作
    if(root1 == root2) return;
    else nation[root2]=root1; //否则合并两个集合
}

int find(int i) //找到该点的头结点,可以用find(x)==find(y)判断两个结点是否在同一个集合
{
    int root=nation[i];
    while(root!=nation[root]) root=nation[root];
    return root;
}

二叉树的非递归遍历

颜色遍历法

//非递归的写法,颜色遍历法
vector<int> preorderTraversal(TreeNode* root) {
    vector<int> ans;
    if(!root) return ans;
    vector<pair<int,TreeNode*>> stk;
    stk.push_back({0,root});
    while(!stk.empty()){
        int color=stk.back().first;
        TreeNode* p=stk.back().second;
        stk.pop_back();
        if(!p) continue;
        if(color==0){
            stk.push_back({0,p->right});
            stk.push_back({0,p->left});
            stk.push_back({1,p});
        }
        else ans.push_back(p->val);
    }
    return ans;
}

scanf函数用法

Clip_2024-02-10_22-32-03

读入一整行字符

在读入一整行之前,应该先用getchar()捕获上一行输入的回车

int n;
cin>>n;
getchar();  //捕获缓冲区的回车
string s;
getline(cin,s);  

用sscanf()分离读入后的字符串

在输入比较复杂时,用sscanf分离变量

/* 输入样式
17:48:19 21:57:24
11:05:18 15:14:23
17:21:07 00:31:46 (+1)
23:02:41 16:13:20 (+1)
10:19:19 20:41:24
22:19:04 16:41:09 (+1)
*/
//读入方式
string s;
int h1,m1,s1,h2,m2,s2,sec,d;
getline(cin,s);
if(s.back()!=')') s=s+" (+0)"; //string.back()表示最后一位字符
sscanf(s.c_str(),"%d:%d:%d %d:%d:%d (+%d)",&h1,&m1,&s1,&h2,&m2,&s2,&d); //string.c_str()表示字符串string的字符串引用

快排模板(do while循环)

void quick_sort(int q[], int l , int r)
{
    if(l>=r) return;
    
    int i=l-1, j=r+1 ,x=q[(l+r)/2];
    
    while(i<j)
    {
        do i++; while(q[i]<x);
        do j--; while(q[j]>x);
        if(i<j) swap(q[i],q[j]);
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}

树状数组函数模板

int lowbit(int x) //返回二进制下最末位的1及后面的0组成的数值
{
  return x & -x;
}

void add(int x, int v) //在原数组下标为x的位置加上数值v,维护tr[](树状数组)
{
  for(int i = x ; i < = N ; i += lowbit(i) ) tr[i] += v;
}

int query(int x) //求原数组下标为x的位置的前缀和,[x,y]连续区间的和 = query[y] - query[x-1];
{
  int ans = 0;
  for(int i = x; i > 0;i -= lowbit(i) ) ans += tr[i];
  return ans;
}

用memset()函数给数组赋值

在初始化除char以外的数组时,只能初始化为0或-1。

const int N=1e6+5;
int f[N];
char a[N];
memset(f,0,sizeof(f)); //将int数组全部赋值为0
memset(a,'s',sizeof(a)); //将char数组全部赋值为字符s

错误用法
memset(f,1,sizeof(f));
因为memset是 逐字节 拷贝,以num为首地址的8字节空间都被赋值为1,即一个int变为 0X00000001 00000001 00000001 00000001,显然,把这个数化为十进制不会等于1的。

posted @ 2022-03-26 17:46  longwind7  阅读(62)  评论(0编辑  收藏  举报