zoukankan      html  css  js  c++  java
  • cpp 学习笔记

    1、C++中模仿gets是  getline(cin, string object)

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    struct CanyBar {
        string info; // 存储匹萨的品牌
        double weight; // 披萨的重量
        double diameter;; // 披萨的直径
        void showInfomation();
    } piSa;
    void CanyBar::showInfomation() {
        cout << "品牌" << " " << info << endl;
        cout << "重量" << " " << weight << endl;
        cout << "直径" << " " << diameter << endl;
    }
    void work() {
        cout << "请输入披萨的品牌 :";
    //    getline()
        getline(cin, piSa.info);
    //    cin >> piSa.info;
        cout << "请输入披萨的直径 :";
        cin >> piSa.diameter;
        cout << "请输入披萨的重量 :";
        cin >> piSa.weight;
        piSa.showInfomation();
    }
    
    int main() {
    //#ifdef local
    //    freopen("data.txt", "r", stdin);
    ////    freopen("data.txt", "w", stdout);
    //#endif
        work();
        return 0;
    }
    View Code

    2、C++的array好像没什么用啊,

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    void work() {
        array<double, 3> a;
        double sum = 0;
        cout << "请输入三次40米跑成绩" << endl;
        for (int i = 0; i < 3; ++i) {
            cin >> a[i];
            sum += a[i];
        }
        cout << sum / 3 << endl;
    }
    
    int main() {
        work();
        return 0;
    }
    View Code

    3、input file stream    ----> ifstream      input  output stream ---> iostream

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    void work() {
        ifstream input("data.txt");
        char ch;
        int ans = 0;
        if (input.is_open()) {
            string s;
            while (!input.eof()) {
                input.get(ch);
                ans++;
            }
            input.close();
            cout << ans - 2 << endl; //会读取'
    ',
            //回车 + 换行 两个字符
        }
    }
    
    int main() {
    //#ifdef local
    //    freopen("data.txt", "r", stdin);
    ////    freopen("data.txt", "w", stdout);
    //#endif
        work();
        return 0;
    }
    View Code

    4、要返回指针,不能用局部变量

    // arrfun3.cpp -- array functions and const
    #include <iostream>
    const int Max = 5;
    
    // function prototypes
    int* fill_array(double ar[], int *begin, int *end);
    void show_array(const double ar[], int *end);  // don't change data
    void revalue(double r, double ar[], int *end);
    
    int main() { //要返回指针,不能用局部变量
        using namespace std;
        double properties[Max];
        int begin = 0, end = 5;
        int *size = fill_array(properties, &begin, &end);
        show_array(properties, size);
        if (*size > 0) {
            cout << "Enter revaluation factor: ";
            double factor;
            while (!(cin >> factor)) {  // bad input
                cin.clear();
                while (cin.get() != '
    ')
                    continue;
                cout << "Bad input; Please enter a number: ";
            }
            revalue(factor, properties, size);
            show_array(properties, size);
        }
        cout << "Done.
    ";
        // cin.get();
        // cin.get();
        return 0;
    }
    
    int * fill_array(double ar[], int *begin, int *end) {
        using namespace std;
        double temp;
        static int i;
        for (i = *begin; i < *end; i++) {
            cout << "Enter value #" << (i + 1) << ": ";
            cin >> temp;
            if (!cin) {  // bad input
                cin.clear();
                while (cin.get() != '
    ')
                    continue;
                cout << "Bad input; input process terminated.
    ";
                break;
            } else if (temp < 0)   // signal to terminate
                break;
            ar[i] = temp;
        }
        return &i; //这个会消失,所以用不了,或者static
    }
    
    // the following function can use, but not alter,
    // the array whose address is ar
    void show_array(const double ar[], int *end) {
        using namespace std;
        for (int i = 0; i < (*end); i++) {
            cout << "Property #" << (i + 1) << ": $";
            cout << ar[i] << endl;
        }
    }
    
    // multiplies each element of ar[] by r
    void revalue(double r, double ar[], int *end) {
    //    cout << (*end) << endl;
        for (int i = 0; i < (*end); i++)
            ar[i] *= r;
    }
    View Code

    5、template <typename T>

     模板不会生成函数的定义,也就是不会生成

    void work() {

       printf("fff"); // 这样的具体的函数

    }

    但是它却会生成函数定义的方案

    template <> void swap(int &, int &); // 显示具体化

    template <> void swap<int>(int &, int &); // 显示具体化

    template void swap(int &, int &); // 显示实例化,少了一个在template后面的<>

    title1:编写一个模板函数,接受一个类型为T的数组,和一个n表示数组长度

    寻找数组中最大值。

    template <class T>
    T maxn(T *a, int len) {
        T mx = a[0];
        for (int i = 1; i < len; ++i) mx = max(mx, a[i]);
        return mx;
    }

    需要一个实例化,接受一个char *str[]的数组,数组中每一个指针指向一个字符串,然后求出最长的那个字符串。

    关键是怎么传参,先来探讨下二维数组要怎么传参

    int f[12][N];
    void fun(const int f[][N]) {
        f[1][0] = 1; // 编译失败
        printf("%d
    ", f[1][0]);
    }

    ①、第二维的大小必须指出,因为,f[1][0]的寻址方式是,*((*(f + 1)) + 0),因为二维数组中,在内存里面也是连续存放的,需要告诉系统,每次 + 1需要跳多远,就是跳N格。

    ②、要知道其本质,二维数组的名字,就是一个指向长度为N的一维数组的指针。这样是得f + 1每次跳N格就好。

    所以,是这样写

    void fun(const int (*f)[N]) {
        printf("%d
    ", f[1][2]);
    }

    ③、如果你是用int **p = new的,则需要fun(int **p),也就是什么样的类型,什么样的形参

    二维数组传参

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    template <class T>
    T maxn(T *a, int len) {
        T mx = a[0];
        for (int i = 1; i < len; ++i) mx = max(mx, a[i]);
        return mx;
    }
    template <> char * maxn(char *str[], int len) {
        char *id = str[0];
        int mx = strlen(str[0]);
        for (int i = 1; i < len; ++i) {
            if (mx < strlen(str[i])) {
                mx = strlen(str[i]);
                id = str[i];
            }
        }
        return id;
    }
    int a[22];
    char *str[222];
    void work() {
        for (int i = 0; i < 4; ++i) str[i] = new char[22];
        strcpy(str[0], "22");
        strcpy(str[1], "23");
        strcpy(str[2], "232");
        strcpy(str[3], "1");
        cout << maxn(str, 4) << endl;
    }
    
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code

    char **str,不是二维数组,他是二级指针,和char *str[]一样

    所以是这样

    char **str;

    str = new char *[4]; //先分配
    for (int i = 0; i < 4; ++i) str[i] = new char[22];

    而二维数组 char str[][],对应的是char (*str)[]

    int (*p)[22] = new int[33][22]; // 可以

    int (*p)[c] = new int[22][c]; // 不可以。形参不可以。

    const int c = 22;

    int (*p)[c] = new int[22][c]; //可以

    #include <bits/stdc++.h>
    #include <windows.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    struct Node {
        int w, v; // w物品重量, v是物品体积
        Node(int _w, int _v) : w(_w), v(_v) {}
    };
    int calc_dp(const vector<Node> vc, const int c) { //c是背包容量
        int **dp = new int *[vc.size()];
        for (int i = 0; i < vc.size(); ++i) dp[i] = new int[c + 1];
    //    int (*dp)[c + 1] = new int[vc.size()][c + 1];  这样不行
        for (int i = 0; i < vc.size(); ++i) dp[i][0] = 0;
        for (int i = 0; i <= c; ++i) {
            if (i >= vc[0].w) dp[0][i] = vc[0].v;
            else dp[0][i] = 0;
        }
    
        bool *sel = new bool[vc.size()];
        for (int i = 0; i < vc.size(); ++i) sel[i] = false;
    
        for (int i = 1; i < vc.size(); ++i) {
            for (int j = 0; j <= c; ++j) {
                if (j >= vc[i].w) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vc[i].w] + vc[i].v);
                else dp[i][j] = dp[i - 1][j];
            }
        }
        int tc = c;
        for (int i = vc.size() - 1; i >= 1; --i) {
            if (dp[i][tc] != dp[i - 1][tc]) {
                sel[i] = true;
                tc -= vc[i].w;
            }
        }
        if (tc) sel[0] = true;
        for (int i = 0; i < vc.size(); ++i) printf("%d ", sel[i]);
        printf("
    ");
        return dp[vc.size() - 1][c];
    }
    
    int mxState, mxValue;
    
    void calc_baoli(const vector<Node> vc, int c, int now, int state, int ans) { // calc_baoli(vc, c, 0)
        if (now == vc.size()) {
            if (mxValue < ans) {
                mxValue = ans;
                mxState = state;
    //            printf("%d %d
    ", ans, state);
            }
            return ;
        }
        calc_baoli(vc, c, now + 1, state, ans);
        if (c >= vc[now].w) {
            calc_baoli(vc, c - vc[now].w, now + 1, state | (1 << now), ans + vc[now].v);
        }
    }
    
    int calc_greedy(const vector<Node> vc, int c) { // calc_greedy(vc, c)
        vector< pair<double, int> > b;
        b.clear();
        for (int i = 0; i < vc.size(); ++i) b.push_back(make_pair(1.0 * vc[i].v / vc[i].w, i));
        sort(b.begin(), b.end(), greater< pair<double, int> >());
        bool *sel = new bool[vc.size()];
        for (int i = 0; i < vc.size(); ++i) sel[i] = false;
        int ans = 0;
        for (int i = 0; i < b.size(); ++i) {
            if (c >= vc[b[i].second].w) {
                c -= vc[b[i].second].w;
                ans += vc[b[i].second].v;
                sel[b[i].second] = true;
            }
        }
        for (int i = 0; i < vc.size(); ++i) printf("%d ", sel[i]);
        printf("
    ");
        return ans;
    }
    void work_dp(vector<Node> vc, int c) {
        long long be = clock();
        printf("动态规划的答案: %d  时间: ", calc_dp(vc, c));
        long long t = clock() - be;
        printf("%lld
    
    ", t);
    }
    
    void work_greedy(vector<Node> vc, int c) {
        long long be = clock();
        printf("贪心的答案: %d 时间: ", calc_greedy(vc, c));
        long long t = clock() - be;
        printf("%lld
    
    ", t);
    }
    
    void work_baoli(vector<Node> vc, int c) {
        long long be = clock();
        mxState = 0, mxValue = -1;
        calc_baoli(vc, c, 0, 0, 0);
        for (int i = 0; i < vc.size(); ++i) {
            if (mxState & (1 << i)) {
                printf("1 ");
            } else printf("0 ");
        }
        printf("
    ");
        printf("暴力的答案: %d 时间: ", mxValue);
        long long t = clock() - be;
        printf("%lld
    
    ", t);
    }
    
    void work() {
        vector<Node> vc;
        vc.clear();
        int n, c;
        srand(time(NULL));
        printf("---------请输入背包容量-------------------
    ");
        scanf("%d", &c);
        printf("---------请输入物品个数-------------------
    ");
        scanf("%d", &n);
        printf("---------请输入%d个物品-------------------
    ", n);
        for (int i = 0; i < n; ++i) {
            int w, v;
             w = rand() % 10 + 1;
             v = rand() % 20 + 1;
             printf("%d %d
    ",w,v);
            vc.push_back(Node(w, v));
        }
        work_dp(vc, c);
        work_greedy(vc, c);
        work_baoli(vc, c);
    }
    
    int main() {
    //#ifdef local
    //    freopen("data.txt", "r", stdin);
    ////    freopen("data.txt", "w", stdout);
    //#endif
        work();
        return 0;
    }
    View Code

    函数调用时候选择的优先级

    1、完全匹配,但常规函数优于模板

    2、提升转换,char和short自动去int, float自动去double

    3、标准转换,int 转为  char, long 转为 double

    4、用户定义的转换

    6、在函数中的形参放入const,只是一个修饰符,表明这个形参是不可以变化的,不是定义一个不可变化的常量一样。

    所以当我们传入参数进去的时候,不用以为const也是可变的。这里的const和const int a = 1, //a不可变,是不同的。

    和重载运算符那个一样的。

    再比如strcmp(const char * str, const char * sub) // 这个称谓常量指针,确保这个指针不能修改那块内存的东西,但是却可以改变这个指针指向的内存位置。  “传入来的指针就算变了指向,和一开始的也是没关系的

    相当于我把家里的钥匙复制一份给你,你把他扔了,和我无关”

    还有一个就是指针常量, int * const p = &a,说明这个指针的指向不能再改变。

    指针常量和常量指针

    1、模板函数、或者模板类需要在.h文件下给出函数的定义,因为在其他一个cpp里面,只include了它的.h文件,所以如果你只是声明了的话,在cpp里面就无法找到它的定义,也就是无法按照模板生成一个具体的函数了,这样做编译的时候没问题,连接程序的时候会失败。

    解决方案

    1、include file2.cpp,这个操作很骚

    2、在file2.cpp中来一个显式实例化,但是这就违背了模板的作用,难道你为每一个都显式实例化吗。也好,分为int和double两种而已。

    3、在.h中给出定义(最优), STL也是这么用

    https://zhidao.baidu.com/question/1946414924223767268.html

    -------------------------2017年12月22日 21:01:30--------------------------------------------------

    输入的东西会放去缓冲区,比如输入两个string1, string2可以cin >> s1, cout << s1, cin >> s2,也是可以得。

    就是asb  sba

    这样可以两个串都同时得到。

    用cin.sync();  可以清除缓冲区,这样第二个字符串就输入不了了。或者fflush(stdin)

    http://blog.csdn.net/livecoldsun/article/details/25489429

    注意用cin.get(str, 6, 结束符),只能最多读取5个字符,因为有一个是回车,而且他不接受回车,让它留在缓冲区、   

    --------------------------------------2018-1-4 14:19:13-------------------------------------------------------------

    如果一个函数是返回一个引用,这个时候就要注意了,因为返回引用的话,calc(val) = 2是可以直接赋值的,这样在if的时候可能会出错

    虽然我觉得if那里很难写错,可能以后熬夜写代码会写错。

    所以,应该考虑下是否要放回const的引用。

    1 int & calc(int val) {
    2     int ans = 0;
    3     while (val / 10 > 0) {
    4         ans += val % 10;
    5         val /= 10;
    6     }
    7     ans += val;
    8     return ans;
    9 }
    没返回const,危险

    重载运算符的时候,我刚才在重载 = 这个运算符,这个运算符应该是在里面搞事。

    先说说重载会怎样。

    比如重载了+号,那么a + c就会退化成a.operator+(c),调用这样的一个函数。

    然后a = a + c,返回一个一模一样类型的值给a,所以a的值有改变。。。。

    我刚才也一样,重载了 = ,也是返回一个一模一样的类型值,以为a = c也会返回一个一模一样的值给a,实则不然。

    这其实相当于a.operator=(c),然后就没了,他不是a = a.operator=(c),就算是这样,也是徒劳,递归一次就知道这是错的。

    所以重载 = 应该是在里面搞事,在里面就改了a的值了。而重载其他的 + 之类的,直接重载即可。

    再一次解释,因为它一般会这样用,a = a + c这样退化成a = a.operator+(c);,这样返回一个一模一样的类型,赋值给a,是可以得。

    2018-09-10 10:38:45

    1、类的初始化成员列表用处是:修改类内部的const int a;成员,这个必须在初始化成员列表里面弄。

    2、派生类使用不了基类的protected成员,只能在派生类里面的方法里使用。比如在派生类B中定义print(B &test),接受一个B类型的对象,在里面调用就可以

  • 相关阅读:
    oracle 进阶之model子句
    SiteMesh的使用--笔记
    JZ49:把字符串转换成整数
    面试题45:把数组排成最小的数
    面试题43:1~n整数中1出现的次数
    面试题42:连续子数组的最大和
    面试题41:数据中的中位数
    面试题40:最小的k个数
    面试题39:数组中出现次数超过一半的数字
    面试题38:字符串的排列
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7687176.html
Copyright © 2011-2022 走看看