ACM算法入门之C++

#included<math.h>  -> pow(a,b)输出的事一个浮点数,相比情况下相乘求平方数会快一点;

  • 语句在头文件<stdio.h>里面,等等C语言中的这些C++同样适用,只要引入相同的头文件,换一个写法即可!
  • 数组只能通过指针传递,不能通过值来传递。数组参数属于指针参数,指针参数即是传址参数(或叫引用参数),如果想在函数中修改参数的值,这是唯一的途径。如果把数组当做参数,不管愿意与否,它就是指针,指向第一个值的指针。所以说,诸如:
    struct node{
        int grade;
        char name[20];
    };
    v.name=num[i].name;   //这样的语句是错误的,估计只能通过循环遍历数组来一个一个的传递!
    但是可以输入,例如:cin>>v.name;    // 就不会报错!
    数组名是一个地址“常量”,是个const!不能被赋值。不能给数组赋值,只能给数组中的变量赋值,cin>>v.name;就是给数组中的变量赋值,这里可以是cin>>v.name;不用加下标的原因是前面定义的是char的数组,cin会做自动类型转化。其他数组例如整型的int数组要通过循环来输入;
  • sqrt是平方,sqrt(3)意思是3的平方,而pow(3,2)也能达到一样的效果,sqrt是pow下的一个小函数而已,但是注意pow返回值是double类型的值,所以显然,sqrt返回值也是double类型的!
  • void initList(List &L);这个函数表明传进去的书库类型是L的地址,而不是L这个数的值,所以主函数中调用,只需要initList(L);这样就可以了,因为initList会自动把L的地址传进函数里面!

  • C语言中的输出字符串的函数有printf,puts,fputs等,字符串中可以是任意的字符,包括空格在内,吴特殊处理,但是输入带有空格的字符串时,只能用gets()或者fgets(),这是因为scanf("%s")输入字符串时,遇到空格就结束了输入。而gets()函数是以回车作为结束符的输入函数,可以输入带空格的字符串。
  • int *n = new int(10)的意思是将指针变量n指向一个整型的数,数的值为10。输出的时候cout<<n;表示输出的是n指向数据的地址值,而cout<<*n;表示输出n所指向的数据的值。利用new int[]或者new int()的方法时,赋值的对象必须是指针,所生成的变量是动态创建,利用堆存储,像是int a=10;则是静态创建,利用栈存储。例如:
    int *she=new int[3];
    she[0]=10;
    she[1]=12;
    cout<<she[1]<<endl;
    结果会打印出12,记住动态分配的用法,分配数组时,赋值还有输出都不是*she,而是she,但是分配的是变量时,例如int *she=new int(2);赋值,还有输出都要*she,例如cout<<*she<<endl;
  • 指针的知识点:
    指针变量初始化的方法是int a;int *p;p=&a;这样才是规范的写法!!不允许把一个数赋予指针变量,故下面的赋值是错误的: int *p;p=1000; 被赋值的指针变量前不能再加"*"说明符,如写为*p=&a 也是错误的。要记住:在int *p之后,*p对应的是指针指向数据的"值",p是指针指向数据的地址。
    像:

    #include<stdio.h>
    int main(void)
    {
    int a=10;
    int *she = a;
    printf("she=%d",she);
    //int a=10;int *she;she=&a;printf("she = %d",*she);这样才是正确的写法。
    }这样的写法是不归范的,在C里面可以通过编译,但是C++不能通过,所以要规范写法!而且这样写之后在C里面也只能通过printf("she=%d",she);这样来输出,这样是错误的,请忘记它!
    链表之中的指针之所以忽略掉了地址符&,只因为它们本身就是地址,实际上没有忽略!例如:struct node *head,*p,*q;p=q;这样不存在错误,要知道,q本身表示的就是地址什么0x69feec这些,所以把它赋给指针p不存在问题,语句表达的意思就是p指向q。而之前错是因为int a=10;a代表的不是一个地址,而是整型数据10,所以&a才能表示a的地址。

  • #include<algorithm>是C++特有的STL模板的算法头文件,包含了一些特定的算法函数,包括sort(),stable_sort(),partical_sort(),nth_element()等常用的函数,其中sort()快排,max()返回迭代等等。
  • 用最简单的递归算法实现求最小公因数:
    int gcd(int a,int b){
        if(b==0)  return a;
        return gcd(b,a%b);
    }
  • swap(a,b)交换函数,是定义在std空间里面的,可以直接使用
  • 头文件之vector:

     vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。vector对象可以在运行时高效地添加元素,并且vector中元素是连续存储的。
    注:vector容器内存放的所有对象都是经过初始化的。如果没有指定存储对象的初始值,那么对于内置类型将用0初始化,对于类类型将调用其默认构造函数进行初始化(如果有其它构造函数而没有默认构造函数,那么此时必须提供元素初始值才能放入容器中)。也就是使用之前要像vector<int> v;这样来初始化,这样,v就是一个可用的数组了。

                          1. v.push_back(t)    在数组的最后添加一个值为t的数据

             2.    v.size()       当前使用数据的大小,也就是v数组中的元素个数

             3.    v.empty()      判断vector是否为空

             4.    v[n]           返回v中位置为n的元素
    举例使用,如何使v生成一个有规律的数组:
    int h=1;

    h=2h+1
    v.push_back(h);
    //v={3,5,7.......}

  • scanf函数的输入执行速度会比cin函数要快,遍历输入函数时,可以用scanf!
  • 重点总结:
    1.不要随便的去定义一个全局变量,因为子函数的调用会改变全局变量的值,而且有时候会发生不可控
    制的程序运行出错,所以,应当减少全局变量的使用!C++中支持for(int i;;)这样的写法,所以什么时候要用到循环变量就什么时候定义,不能贪懒。
    2.using namespace std;这个语句应当在引入头文件的下方就写出,不然空间std里面的什么都无法调用,会使程序出现bug;例如:vector<int> G;应当出现在using namespace std;这个语句的后面,不不然程序会报错!
    3.在C++中,函数声明是必要的,如果自定义函数没有函数声明而去调用函数,编译器会报错
  • 知识点:如何给字符串赋值或者初始化:
    在C++中,定义字符串的语句是:string c="hello";string并不用引入什么,存在于空间std中,当你试图cout<<c[1];时,你会得到字母e ,C语言中的char *c="hello";这样的写法在C++中不适用,会有警告,但是可以运行;
    1.     string s3 = "hiya";       cout<<s3;-->hiya
    2.     string s4(10, 'c');       cout<<s4;-->cccccccccc
    3.     string s5(s3 + s4);       cout<<s5;-->hiyacccccccccc
  • 接上面的继续讲,重要的点要来了:
    那些#include<cstring>里面的strcmp函数,还有strlen函数,都是要求参数类型是char*类型的,所以如果要用上这些函数的话,就要做如下改变:
    1.使用std::string的c_str接口,该接口会返回一个const char*的指针,正好可以作为参数传递给strcmp或者strlen等函数。代码:
    std::string st="hello";   //这里也可以直接给st赋值,不用输入:std::string st="hello";其实                             std::可以省略,有没有都是一样的
    cin>>st;
    i=strlen(st.c_str());    //当然,只是求长度的话,可以使用std::string自带的size接口,直接int                            i=st.size();
    2.方法2就是重新定义字符串,不在使用string来定义字符串,既然strcmp这些函数只能接受char*类型的,那就相应的做出改变!代码:

    char st[]="hello";  //标明与不标明数组的大小都可以,不标的好处是可以初始化多少,数组的长度就是多                        少,但是注意,strcmp只接受char*类型不是要你这样去定义数组,char *s这种                        定义是不规范的;
    int i=strlen(st);
    cout<<i;


  • 向下去取整的实际意思就是往小的方向去取!4<4.5<5,在4.5往下取整就是4
  • 循环输入字符串的方法:(一般用gets()因为scanf()读入不了空格,scanf()遇到空格就结束输入了,而gets()是以回车键作为结束符的,可以读入空格)

    struct node
    {
    char name[1000];     //这里用了结构体,不用的话,就是数组,原理是一样的
    };
    while(1){

    gets(c[i].name);
    if(c[i].name[0]=='#') break;  //意思就是当读入到符号'#'就是结束输入
    .....
    }

  • 自定义的结构体不要申请太大的数组,不要回越界发生错误,就比如接上一个知识点的结构体,如果
    struct node
    {
    char name[1000];     
    };
    node C[10000];//这时候就会发生错误,申请内存太大,越界??还没有弄清楚,暂存
原文地址:https://www.cnblogs.com/myxdashuaige/p/8127233.html