经验

  • 只定义变量而不赋值,要比定义变量的同时并赋值更快。 使用endl比使用'\n'换行要快
  • cin.getline(str, sizeof(str));这样子原str多出的空间将被弃掉。
  • 使用iterator访问vector如 ptr=a.end(),a.end()是0哨兵位

技巧

翻转数组

将数组取倒数的方法,同时也是求解回文串的方法。

    for(int i=0;i<len;i++){
        arr1[len-1-i] = arr[i];
    }

双指针法

一种将数组内元素移位的方法

void func(int* p, int n) {

int id=0;
int temp;
for(int i=0;i<n;i++){
if(p[i]!=0){
    temp = p[i];
    p[i] = p[id];
    p[id++] = temp;
    
}}

}

对对象排序

根据对象内属性进行排序

bool operator>(Employee &a,Employee &b){
    return(a.getSalary()>b.getSalary());
sort(employees.begin(),employees.end(),greater<>());

算法

递归

递归,首先得确定递归表达式即Xn=f(Xn1)X_{n}=f(X_{n-1}),以及结束条件

int function(int n){
if(condition) return X1;
return f(x_(n-1)) 
}

选择排序

选择排序与冒泡排序的差别是,选择排序选择每次循环选出最大或最小值的索引,只交换最值和i的值。不进行其他交换。

比较字符串大小的方法

int mystrcmp(const char* src, const char* dst) {
int sum_src = 0;
int sum_dst = 0;
int i=0;
int n_src = strlen(src);
int n_dst = strlen(dst);
//如果第n个字符不相等,则大字符的字符串大
//如果第n个字符串相等,则比较下一个字符串
//如果比较了所有对应字符都相等,则有剩余字符的字符串大
while(i<n_src&&i<n_dst){
    if(src[i]>dst[i])return 1;
    else if(src[i]<dst[i])return -1;
    else{
        i++;
    }
}
if(i<n_src) return 1;
else if(i<n_dst) return -1;
else return 0;
    
    // write your code here......
    

}

滑窗法,求字串

int main() {

    char str[100] = { 0 };
    char substr[100] = { 0 };

    cin.getline(str, sizeof(str));
    cin.getline(substr, sizeof(substr));
    int n_str = strlen(str);
    int n_substr = strlen(substr);
    int count = 0;
    for(int i=0;i<=n_str-n_substr;i++){
        int t=0;
        for(int j=i;j<i+n_substr;j++){
            if(str[j]!=substr[t]) break;
            t++;
        }
        if (t==n_substr) count += 1;
    }
    

    cout << count << endl;

    return 0;
}

语法

  • 连续输入使用std::cin>>a>>b;
  • 三元运算法a>b?a:b如果a>b,则选择a,否则选择b.
  • swap:交换变量值
  • round在cmath库中,且只能四舍五入到整数
  • round只能四舍五入到整数。 #include <iomanip> cout << fixed << setprecision(1) << cost << endl;则可以选择保留几位 小数

二维数组

int arr[4][3] = {
        22,66,44,
        77,33,88,
        25,45,65,
        11,66,99
    };

输入字符串的方法

 string s1, s2;
 getline(cin, s1);
 getline(cin, s2);

结构体

参考http://c.biancheng.net/view/1407.html

struct student {
    string name;
    int age;
    float height;
};

student stu = {name,age,height};
cout<<stu.name<<' '<<stu.age<<' '<<stu.height;

指针

int *ptr=arr;

cout<<*ptr;//访问值
cout<<ptr;//访问内存地址
ptr++;//获取下一个内存地址
ptr==nullptr;//判断空指针

动态数组

关于这个声明符[]的所在位置的含义

 int *p = new int [n];
delete []p;//删除掉数组,而不是指针

数组

char str[30] = { 0 }//声明数组

可见域

在母函数中定义的变量,即使不使用引用,在子函数中对该变量进行操作,结束子函数后,在子函数的操作仍在母函数中可见。

浅拷贝与深拷贝

python的深浅拷贝

浅拷贝是指,仅对第一层嵌套对象进行拷贝,对copy改变第一层嵌套对象,不会影响原对象。但如果改变第二层,则会导致原对象的第二层嵌套也同样发生改变。参考https://zhuanlan.zhihu.com/p/74527997

C++的浅拷贝与深拷贝

C++的浅拷贝是指拷贝时,生成的指针仍指向同一片内存空间。 深拷贝是指将内容复制到新的内存空间。 在对对象进行拷贝,如果使用浅拷贝,会导致跳出程序后,对同一内存空间执行两次析构函数,从而造成对某对象删除两次,引起错误。 参考https://blog.csdn.net/caoshangpa/article/details/79226270

多态与虚函数

指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。

必须是基类指针指向派生类对象,派生类指针不能指基类。所以派生类只能操作父类有的属性及函数。对于那些父类没有的属性,必须将父类指针强制转化为子类指针后才可使用。 virtual int getResult(){}

整数字符串与int类型的整数相互转换

int atoi(const char *nptr);将整数字符串转换成int类型的整数 to_string(double __val);将doubel类型的整数转换成整数字符串

分割字符串

char strtok(char str, const char * delim); 将字符串按照 delim 中的字符进行分割。当 strtok() 在参数 str 的字符串中发现参数 delim 分割字符时,则会将该字符改为 \0 字符,当连续出现多个时只替换第一个为 \0。在第一次调用时,strtok() 必须给与参数 str 字符串,往后调用则将参数 str 设置为 空指针,每次调用成功则返回指向被分割出片段的指针。

//msg是指针字符数组
//i=0时,对存储的第一个字符串进行转换
//随后迭代对第i个字符串进行转换
while ((msg[i] = strtok(msg[i], " ")) && ++i);