c++刷题常用的数据类型

在使用c++刷题的过程中,经常会碰到python顺手就来但是c++里面就是不会用的数据类型和数据结构,这里做一些总结
所有用到的数据类型结构包括但不限于:

整数,数组,字典,集合,字符串,小根堆

1、整数

整数没啥好说的,直接int a结束,但是要注意溢出的问题

2、数组

python中的数组非常简单,而且元素是可以通过append直接添加的,但是c++中的常规数组在定义的时候就要确定长度,除非使用vector或者new一个长度为a的数组,python中的列表更像是c++中的vector

    // 使用new来创建动态数组
    int len=8;
    int*arr = new int[len];
    // 使用vector来创建动态数组
    int len=8;
    // arr(len)注意是括号不是[],而且里面放的是长度
    // 如果要全部初始化成0,可以这样: vector<int> arr(len,0);
    vector<int> arr(len,0);
    // 初始化为特定的值
    for(int i=0;i<len;i++){
    
    
        arr[i]=i;
    }
    // 直接遍历vector中的元素,类似于 for i in nums
    for(int num:arr){
    
    
        printf("%d\n",num);
    }
    // 对arr进行切片,类似于 b=a[x:y],左闭右开,下面的操作就是
    //     subarr=arr[0:4]
    vector<int> subarr(arr.begin()+0,arr.begin()+4);

    // 追加一个元素,即append
    arr.push_back(8);

    // 排序,即arr.sort(reverse=True),需要#include<algorithm>
    // 最后一个参数greater<int>()用来降序,不写就是升序
    sort(arr.begin(),arr.end(),greater<int>());

	// 原生数组的使用
    // 通过定义一个const变量来设置原生数组的长度
    const int b_size=300;
    int b[b_size];
    // 成批初始化数组,注意memset需要#include<string.h>
    // 特别注意,memset是按照字节操作的,所以3*sizeof(int)
    //  是将b的前3个元素的每一个字节都设置为-1,由于-1的二进制是全为1
    //  所以最终这三个元素都是-1,如果换成其他的数就不好使了,但是这3个数
    //  仍然会是一样的,后面没有初始化的297个数是随机的
    memset(b,-1,3*sizeof(int));
    for(int i=0;i<4;i++)printf("b[%d]=%d\n",i,b[i]);
    int a[7]={
    
    1,2,3,4,5,6,7};
    // c++的原生数组没有size属性,不能直接得到,只能自己算出来
    //    而且,一般用于循环遍历的变量类型是size_t,不是int,也不是unsigned int
    size_t size=sizeof(a)/sizeof(a[0]);
    for(size_t i=0;i<size;i++){
    
    
        // 格式化输出时,size_t类型的变量有属于自己的格式占位符%u,表示无符号整数
        printf("a[%u]=%d\n",i,a[i]);
    }
}

3、字典

python中的字典dict中常用的是defaultdict,可以指定默认的值。
c++中的map对默认将键值对按照键升序排列,所以要看情况使用 unordered_map

    map<int,int> mymap;
    // 可以先判断这个键在不在里面,如果不在则刻意指定
    if (mymap.find(1)==mymap.end()){
    
    
        mymap[1]=10; // 添加元素和python一样
    }

    // 遍历字典
    for(auto iter=mymap.begin();iter!=mymap.end();iter++){
    
    
        printf("key=%d, value=%d\n",iter->first,iter->second);
    }
    
    // 查看map的大小
    int size=mymap.size();
    // 删除某个键值对,删除成功返回1,否则返回0
    int state = mymap.erase(1);

    // 清空整个字典
    mymap.erase(mymap.begin(),mymap.end());
    // 或者
    mymap.clear();

4、集合

对于c++而言,集合 set是一个有序的集合,但是python中的set其实是一个无需的集合,对应于c++中的unordered_set

    unordered_set<int> m_set;
    // 添加元素
    for(int i=0;i<10;i++){
    
    
        m_set.insert(i);
    }
    // 查找元素
    if(m_set.find(4)!=m_set.end()){
    
    
        printf("元素%d在集合中\n",4);
    }
    // 删除指定的元素,成功返回1,否则返回0
    int is_delete = m_set.erase(1);

还有一个非常重要的点是,unorder_set和set的使用范围不同,unorder_set使用哈希表实现,因此内部的元素一定要是可哈希的,但是与python不同,c++中的元素也没有hash函数,所以还不如使用vector来重载一下,因此这里定义一个新的类型MySet,MySet可以直接存储vector类型的数据

#include<unordered_set>
#include<tuple>
#include<iostream>
#include<vector>
using namespace std;

struct VectorHash {
    
    
    size_t operator()(const std::vector<int>& v) const {
    
    
        std::hash<int> hasher;
        size_t seed = 0;
        for (int i : v) {
    
    
            seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
        }
        return seed;
    }
};
using MySet = std::unordered_set<std::vector<int>, VectorHash>;
// 使用也很简单
int main(){
    
    
    MySet mySet;
    mySet.insert({
    
    1,2,3});
    mySet.insert({
    
    3,2,1});
    for(auto it:mySet){
    
    
        cout<<it[0]<<' '<<it[1]<<' '<<it[2]<< endl;
    }
    return 0;
}

5、字符串

    // 一定要以'\0'结尾
    char s[]={
    
    'h','e','l','l','o','\0'};
    // 这样就不需要以'\0'结尾
    char s2[]="world";
    printf("s=%s\n",s);
    printf("s2=%s\n",s2);
    // 查询长度strlen 需要包含头文件string.h
    printf("s的长度是%d个字符\n", strlen(s));
    printf("s的长度是%d个字符\n", strlen(s));

    // 字符串的切片
    string s3="myboy";
    string sliceed = s3.substr(0,2);
    // cout<<"字符串s[0:2]="<<sliceed<<endl;
    // 注意,string是c++特有的类型,printf不能直接输出,需要转换.c_str()
    printf("字符串s[0:2]=%s\n", sliceed.c_str());

猜你喜欢

转载自blog.csdn.net/qq_41926099/article/details/131543194