• C/C++_FAQ_Tips


    对unsigned 赋 负值 ,及与负数运算 (Test)

        unsigned u = -1;
        assert(u == pow(2, sizeof(unsigned) * 8) - 1); //将 -1 转化为unsigned ,再赋给 u
        assert(u + 2 == 1);  //unsigned 溢出, 溢出的数为1
    	u = 2;
        int i = -1;
        assert(u + i == 1); //将-1转换为无符号数,然后再进行相加 , 此处unsigned溢出
    

    More

    四舍五入

    #include <bits/stdc++.h>
    using namespace std;
    
    double Round(double number, unsigned int bits)
    {
        stringstream ss;
        ss << fixed << setprecision(bits) << number;
        ss >> number;
        return number;
    }
    
    int main(void)
    {
        //输出
        double u = 14 / 3.0; //4.66666~
        printf("%.2lf
    ", u);
        cout << fixed << setprecision(2) << u << endl;
        
        //改变原值,四舍五入保留到整数
        assert(round(u) == 5); //调用round()函数
    
        u = (int)(u + 0.5); //巧妙运用类型转换, 若为负数 则 -0.5
        assert(u == 5);
    
        //改变原值,四舍五入到任意小数位
        double i = 14 / 3.0;
        i = Round(i, 2); // 4.670000~
        assert(i - 4.67000 < 1e10);
        
        return 0;
    }
    

    最大公约数GCD , 最小公倍数LCM

    https://oi-wiki.org/math/gcd/

    int gcd(int a, int b)
    {
        return b == 0 ? a : gcd(b, a % b);  //欧几里得算法
    } 
    
    //n个数的最大公约数算法:
    //把n个数保存为一个数组
    //参数为数组的指针和数组的大小(需要计算的数的个数)
    //然后先求出gcd(a[0],a[1]), 然后将所求的gcd与数组的下一个元素作为gcd的参数继续求gcd
    //这样就产生一个递归的求ngcd的算法
    int ngcd(int *a, int n)
    {
        return n == 1 ? *a : gcd(a[n - 1], ngcd(a, n - 1));  
    }
    
    // gcd*lcm=a*b 
    int lcm(int a, int b)
    {
        return a * b / (gcd(a, b));
    }
    
    //n个数的最小公倍数算法:
    //算法过程和n个数的最大公约数求法类似
    //求出头两个的最小公倍数,再将欺和大三个数求最小公倍数直到数组末尾
    //这样产生一个递归的求nlcm的算法
    int nlcm(int *a, int n)
    {
        return n == 1 ? *a : lcm(a[n - 1], nlcm(a, n - 1));
    }
    
    int main(void)
    {
        int a[5] = {18, 12, 30, 24, 36};
        printf("%d %d %d %d", ngcd(a, 5), gcd(18, 12),lcm(10,12),nlcm(a,5));
        return 0;
    }
    

    数字相关

    __int128_t 输入,输出

    inline __int128_t read()
    {
        __int128_t x = 0;
        bool isPositive = true;
        char ch = getchar();
        while (isdigit(ch) == false)
        {
            if (ch == '-')
            {
                isPositive = false;
            }
            ch = getchar();
        }
        while (isdigit(ch))
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return isPositive ? x : -x;
    }
    
    void write(__int128_t x)
    {
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9)
        {
            write(x / 10);
        }
        putchar(x % 10 + '0');
    }
    

    判断一个浮点数是否为整数

    bool IsInteger_1(double x)
    {
        if (x - (int)x == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    bool IsInteger_2(double x)
    {
        if (fmod(x, 1) == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    整数的位数(长度)

    unsigned LengthOfInt(int x)
    {
        unsigned count(0);
        while (x)
        {
            x /= 10;
            count++;
        }
        return count;
    }
    

    数字/字符串 互化

     std::to_string;
    
     atof() :将字符串转换为双精度浮点型值。
     atoi() :将字符串转换为整型值。
     atol() :将字符串转换为长整型s值。
    

    翻转整数 120 -> 21

    int ReverseInteger_1(int x)
    {
        string a = to_string(x);
        stringstream in;
        for (auto i = a.rbegin(); i != a.rend(); i++)
        {
            in << *i;
        }
        int re(0);
        in >> re;
        return re;
    }
    int ReverseInteger_2(int x)
    {
        int temp(0);
        while (x)
        {
            temp = temp * 10 + x % 10;
            x /= 10;
        }
        return temp;
    }
    

    排序算法

    冒泡算法

    #include <stdio.h>
    void bubble_sort(int arr[], int len)
    {
        for (int i = 0; i < len - 1; i++)   //外侧循环次数为 len-1 或 len
            for (int j = 0; j < len - 1 - i; j++)   //内循环次数为  len-1-i
            {
                int temp;
                if (arr[j] > arr[j + 1])   //从小到大             升序
                {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
    }
    int main()
    {
        int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
        int len = (int)sizeof(arr) / sizeof(*arr); //  数组长度
        //sizeof测字节长度.
        //short int 字节长  2 , int,long int,float 字节长为4  ,double ,long long int 字长 8
        bubble_sort(arr, len);
        return 0;
    }
    

    选择排序

    #include <stdio.h>
    void selection_sort(int arr[], int len)
    {
        for (int i = 0; i < len - 1; i++)     //外侧循环次数为 len-1
            for (int j = i + 1; j < len; j++) //内循环 为 len
            {
                if (arr[i] > arr[j])         //从小到大             升序
                {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
    }
    int main()
    {
        int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
        int len = (int)sizeof(arr) / sizeof(*arr); //  数组长度
        //sizeof测字节长度.
        //short int 字节长  2 , int,long int,float 字节长为4  ,double ,long long int 字长 8
        selection_sort(arr, len);
        return 0;
    }
    

    打印问题

    金字塔 _1

            *
          * * *
        * * * * *
      * * * * * * *
    * * * * * * * * *
    
    #include <stdio.h>
    int main(void)
    {
        int rows;
        scanf("%d", &rows);
        for (int i = 1; i <= rows; i++)
        {
            for (int blank = 1; blank <= rows - i; blank++) //打印空格
            {
                printf("  "); //两个空格               第i行有2*(行数-i)个空格
            }
            for (int k = 0; k != 2 * i - 1; k++) //打印(星号+空格) 1-3-5-7-9...
            {
                printf("* ");
            }
            printf("
    ");
        }
        return 0;
    }
    

    倒三角形_1

    #include <stdio.h>
    int main(int argc, char *argv[])
    {
        int rows;
        scanf("%d", &rows);
        for (int i = rows; i >= 1; i--)
        {
            //打印空格
            for (int j = 0; j < rows - i; j++)
            {
                printf("  ");
            }
            for (int j = 0; j < 2 * i - 1; j++)
            {
                printf("* ");
            }
            printf("
    ");
        }
        return 0;
    }
    

    数字三角形

            1
          2 3 2
        3 4 5 4 3
      4 5 6 7 6 5 4
    5 6 7 8 9 8 7 6 5
    
    #include <stdio.h>
    int main(int argc, char *argv[])
    {
        int rows;
        scanf("%d", &rows);
        for (int i = 1; i <= rows; i++)
        {
            //打印空格
            for (int j = 0; j < rows - i; j++)
            {
                printf("  ");
            }
            //左小一半
            for (int k = i; k < 2 * i - 1; k++)
            {
                printf("%d ", k);
            }
            //右大半
            for (int k = 2 * i - 1; k >= i; k--)
            {
                printf("%d ", k);
            }
            printf("
    ");
        }
        return 0;
    }
    

    弗洛伊德三角

     1
     2    3
     4    5    6
     7    8    9   10
    11   12   13   14   15
    16   17   18   19   20   21
    
    #include <stdio.h>
    int main()
    {
        int N;
        scanf("%d", &N);
        int j = 1;
        for (int i = 1; i <= N; i++) //i控制打印行数
        {
            for (int l = 1; l <= i; l++, j++) //l 控制每行打印 l 个数字 
                printf("%5d", j);   //j 为打印出来的数字,实为总共进行循环的次数
            printf("
    ");
        }
        return 0;
    }
    

    字符串相关

    最长回文子串

    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char a[3000];
        gets(a);
        char b[3000];
        int j = 0;
        b[0] = 0;
        for (int i = 1; a[j]; i++)
        {
            if ((i) % 2 == 0)
            {
                b[i] = a[j++];
                b[i + 1] = '#';
                b[i + 2] = 0;
            }
            else
            {
                b[i] = '#';
            }
        }
        //ABCBA -> 0#A#A......#0
        int max = 0;
        for (int i = 1; b[i]; i++)
        {
            int current = 1, count = 0;
            while (b[i - current] == b[i + current] && b[i - current] != 0 && b[i + current] != 0)
            {
                current++;
                count++;
            }
            if (count > max)
            {
                max = count;
            }
        }
        printf("%d", max);
        return 0;
    }
    

    删除字符串中空格

    //Version 1:
    void remove_spaces(char *s)
    {
        char *d = s;
        while (*s != 0)
        {
            while (*d == ' ')
            {
                d++;
            }
            *s = *d;
            s++;
            d++;
        }
    } // https://stackoverflow.com/questions/1726302/removing-spaces-from-a-string-in-c
    
    //Version 2:
    void delete_spaces(char *s)
    {
        for (int i = 0, j = 0; s[i] != 0; i++)
        {
            if (s[i] != ' ')
            {
                s[j] = s[i];
                j++;
            }
        }
        s[j] = 0;
    } 
    

    交并差集

    #include <vector>
    #include <algorithm> //sort函数、交并补函数
    #include <iterator>  //求交并补使用到的迭代器
    using namespace std;
    
    //容器vector中元素的去重
    vector<int> unique_element_in_vector(vector<int> v)
    {
        vector<int>::iterator vector_iterator;
         //使用sort()进行排序,排序后的相同元素集中出现
        sort(v.begin(), v.end());
        //unique()函数将重复的元素放到vector的尾部(无序) 然后返回指向第一个重复元素的迭代器
        vector_iterator = unique(v.begin(), v.end());
        if (vector_iterator != v.end())
        {
            //再用erase函数擦除从这个元素到最后元素的所有的元素。
            v.erase(vector_iterator, v.end());
        }	
        return v;
    }
    
    //两个vector求交并差集
    vector<int> vectors_intersection(vector<int> v1, vector<int> v2)
    {
        vector<int> v;
        sort(v1.begin(), v1.end());
        sort(v2.begin(), v2.end());
    
        set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(v)); //求交集
    
        set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(v)); //求并集
    
        set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(v));
        //求差集   v1中有,v2中没有
        //?差集与补集关系
    
        return v;
    }
    

    迭代器

    Insertion into a vector can invalidate iterators

    children.insert(it, node); // this can invalidate `it', triggering a
                               // segfault during the next iteration
    

    More

    for循环使用 iterator , 并对容器进行 insert , 会 [segmentation fault]

    IO相关

    cin >> 处理空格

    当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符,若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。
    cin>>对缓冲区中的第一个换行符视而不见,采取的措施是忽略清除,继续阻塞等待缓冲区有效数据的到来。但是,getline()读取数据时,并非像cin>>那样忽略第一个换行符,getline()发现cin的缓冲区中有一个残留的换行符,不阻塞请求键盘输入,直接读取,送入目标字符串后,再将换行符替换为空字符’'.

    More

    scanf 读取 换行符

    int n;
    scanf("%d",&n);
    char ch;
    scanf("%c",&ch);
    //以上ch为'
    '
    

    Click here

    scanfgets

    //形似
    int n;char srt[10];
    scanf("%d",&n);
    //getchar();        //解决方法
    gets(str);   //这里gets不会执行
    

    scanf函数在读取字符以外的输入时,
    不接收' ',把' '留存在输入缓冲区中,后面被gets当一个字符接收了;
    gets在读入' '后就认为字符串结束了,所以你啥也没有看到而向下走了。
    解决办法是在gets前加一句getchar(),把那些该死的' '从缓冲区中取走.

  • 相关阅读:
    前端百度地图开发使用总结
    换电脑后如何同步git本地仓库及分支
    vue mint-ui初次使用总结
    git学习入门总结
    深夜,当音乐响起,数据在MySQL中静静的疯狂计算
    且说Tomcat、Servlet、JSP和Spring
    国庆与中秋7天死磕Web的时光
    Android编程初涉,以控制摄像头为例
    谈现阶段如何形成可行的健康生活习惯方案
    说Java网络编程
  • 原文地址:https://www.cnblogs.com/Delta2019/p/12089778.html
Copyright © 2020-2023  润新知