常见C++存储数据类型的用法

(写给未来遗忘的自己)

1.常见类型:

  • 数组:适用于固定大小的场景,访问速度快,但大小固定。
  • vector:动态数组,大小可以自动调整,适用于需要灵活大小的场景。
  • list:双向链表,适用于需要频繁插入和删除的场景。
  • map:关联容器,存储键值对,适用于需要快速查找的场景。
  • 链表:可以使用指针实现,适用于需要动态数据结构的场景

2.使用方法: 

2.1 数组

数组是一种固定大小的数据结构,适用于已知大小的场景。

  • 一维数组:适用于线性数据结构,大小固定。
  • 二维数组:适用于矩阵数据结构,大小固定。
  • 动态数组:适用于在运行时确定大小的数组,需要手动管理内存。

这些示例展示了如何初始化和使用一维和二维数组

#include <iostream>

int main() {
    // 初始化一维数组
    int arr[5] = {1, 2, 3, 4, 5};

    // 或者可以逐个元素初始化
    int arr2[5];
    arr2[0] = 1;
    arr2[1] = 2;
    arr2[2] = 3;
    arr2[3] = 4;
    arr2[4] = 5;

    // 遍历一维数组
    for (int i = 0; i < 5; i++) {
        std::cout << arr[i] << " ";
    }

    std::cout << std::endl;

// 初始化二维数组
    int arr[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    // 或者可以逐个元素初始化
    int arr2[3][4];
    arr2[0][0] = 1; arr2[0][1] = 2; arr2[0][2] = 3; arr2[0][3] = 4;
    arr2[1][0] = 5; arr2[1][1] = 6; arr2[1][2] = 7; arr2[1][3] = 8;
    arr2[2][0] = 9; arr2[2][1] = 10; arr2[2][2] = 11; arr2[2][3] = 12;

    // 遍历二维数组
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }


    return 0;
}

 静态分配和动态分配的情况

#include <iostream>

int main() {
    // 动态分配一维数组
    int* arr = new int[5];

    // 初始化数组
    for (int i = 0; i < 5; i++) {
        arr[i] = i + 1;
    }

    // 遍历数组
    for (int i = 0; i < 5; i++) {
        std::cout << arr[i] << " ";
    }

    std::cout << std::endl;

    // 释放动态数组
    delete[] arr;

// 动态分配二维数组
    int rows = 3;
    int cols = 4;
    int** arr = new int*[rows];
    for (int i = 0; i < rows; i++) {
        arr[i] = new int[cols];
    }

    // 初始化数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            arr[i][j] = i * cols + j + 1;
        }
    }

    // 遍历二维数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }

    // 释放动态数组
    for (int i = 0; i < rows; i++) {
        delete[] arr[i];
    }
    delete[] arr;

    return 0;
}

2.2 vector

vector 是动态数组,可以自动调整大小,适用于需要灵活大小的场景。

#include <iostream>
#include <vector>

int main() {
    // 初始化 vector
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 添加元素
    vec.push_back(6);
    // 删除第三个元素(索引为2)
    vec.erase(vec.begin() + 2);
   // 删除索引为1到3(包括索引1,但不包括索引3)的元素
    vec.erase(vec.begin() + 1, vec.begin() + 4);
   // 删除所有偶数元素
    vec.erase(std::remove_if(vec.begin(), vec.end(), [](int num){ return num % 2 == 0; 
    }), vec.end());
   // 清空整个 vector
    vec.clear();

    // 访问和修改元素
    vec[0] = 10;

    // 遍历 vector
    for (int i = 0; i < vec.size(); i++) {
        std::cout << vec[i] << " ";
    }
/***********************************************************************/
 // 初始化 二维vector
 std::vector<std::vector<int>> vec2d = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    // 访问和修改元素
    std::cout << "Element at (1, 1): " << vec2d[1][1] << std::endl;
    vec2d[1][1] = 10;
    // 要添加的一行元素
    std::vector<int> newRow = {7, 8, 9};

    // 将 newRow 添加到 vec2d 的末尾
    vec2d.push_back(newRow);

    // 遍历二维 vector
    for (int i = 0; i < vec2d.size(); i++) {
        for (int j = 0; j < vec2d[i].size(); j++) {
            std::cout << vec2d[i][j] << " ";
        }
        std::cout << std::endl;
    }

/***********************************************************************/
std::vector<std::vector<std::vector<int>>> vec3d = {
        {
            {1, 2},
            {3, 4}
        },
        {
            {5, 6},
            {7, 8}
        }
    };

    // 访问和修改元素
    std::cout << "Element at (1, 1, 1): " << vec3d[1][1][1] << std::endl;
    vec3d[1][1][1] = 10;

    // 遍历三维 vector
    for (int i = 0; i < vec3d.size(); i++) {
        for (int j = 0; j < vec3d[i].size(); j++) {
            for (int k = 0; k < vec3d[i][j].size(); k++) {
                std::cout << vec3d[i][j][k] << " ";
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
    return 0;
}

2.3 list

list 是双向链表,适用于需要频繁插入和删除的场景。

#include <iostream>
#include <list>

int main() {
    // 初始化 list
    std::list<int> lst = {1, 2, 3, 4, 5};

    // 添加元素
    lst.push_back(6);
    lst.push_front(0);

    // 遍历 list
    for (auto it = lst.begin(); it != lst.end(); ++it) {
        std::cout << *it << " ";
    }

    return 0;
}

2.4 map

map 是一种关联容器,存储键值对,按键排序,适用于需要快速查找的场景。map有三种类型。

  • td::map:有序关联容器,根据键进行排序。
  • std::unordered_map:无序关联容器,使用哈希表实现快速查找。
  • std::multimap:允许重复键的有序关联容器,可以存储相同键的多个值。
#include <iostream>
#include <map>

int main() {
    // 初始化 map
    std::map<int, std::string> mp;
    mp[1] = "one";
    mp[2] = "two";
    mp[3] = "three";

    // 访问和修改元素
    mp[1] = "ONE";

    // 遍历 map
    for (const auto& pair : mp) {
        std::cout << pair.first << ": " << pair.second << "\n";
    }
/**************************************************************************************/

std::unordered_map<int, std::string> myMap;

    // 插入元素
    myMap.insert({1, "apple"});
    myMap.insert({2, "banana"});
    myMap.insert({3, "cherry"});

    // 访问元素
    std::cout << "Value for key 2: " << myMap[2] << std::endl;

    // 遍历 unordered_map
    for (const auto& pair : myMap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
/**************************************************************************************/

std::multimap<int, std::string> myMultimap;

    // 插入元素
    myMultimap.insert({1, "apple"});
    myMultimap.insert({2, "banana"});
    myMultimap.insert({2, "orange"}); // 允许重复键

    // 访问元素
    std::cout << "Values for key 2:" << std::endl;
    auto range = myMultimap.equal_range(2);
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << it->second << std::endl;
    }

    // 遍历 multimap
    for (const auto& pair : myMultimap) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }


    return 0;
}

2.5单向链表

链表是一种动态数据结构,可以使用指针实现,适用于需要动态数据结构的场景。

#include <iostream>

struct Node {
    int data;
    Node* next;
};

int main() {
    // 初始化链表
    Node* head = new Node{1, nullptr};
    head->next = new Node{2, nullptr};
    head->next->next = new Node{3, nullptr};

    // 遍历链表
    Node* current = head;
    while (current != nullptr) {
        std::cout << current->data << " ";
        current = current->next;
    }

    // 释放链表内存
    current = head;
    while (current != nullptr) {
        Node* next = current->next;
        delete current;
        current = next;
    }

    return 0;
}

2.6 双向链表

双向链表比单向链表多了一个指向前一个节点的指针。

#include <iostream>

struct Node {
    int data;
    Node* next;
    Node* prev;
};

int main() {
    // 初始化链表
    Node* head = new Node{1, nullptr, nullptr};
    Node* second = new Node{2, nullptr, head};
    head->next = second;
    Node* third = new Node{3, nullptr, second};
    second->next = third;

    // 遍历链表(向前)
    Node* current = head;
    while (current != nullptr) {
        std::cout << current->data << " ";
        current = current->next;
    }

    std::cout << std::endl;

    // 遍历链表(向后)
    current = third;
    while (current != nullptr) {
        std::cout << current->data << " ";
        current = current->prev;
    }

    // 释放链表内存
    current = head;
    while (current != nullptr) {
        Node* next = current->next;
        delete current;
        current = next;
    }

    return 0;
}

2.7 set

set 是一种关联容器,用于存储唯一值,并且会自动对其进行排序。set 提供了三种常见的类型:std::setstd::unordered_setstd::multiset

  • std::set:有序关联容器,存储唯一值,并根据元素的值进行排序。
  • std::unordered_set:无序关联容器,使用哈希表实现存储和查找,插入和查找的平均时间复杂度为 O(1)。
  • std::multiset:允许存储重复值的有序关联容器,会保持所有插入的元素,并根据元素的值进行排序。
#include <iostream>
#include <set>

int main() {
    // 创建一个 std::set
    std::set<int> mySet;

    // 插入元素
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(5);

    // 遍历 set
    for (const auto& elem : mySet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 检查元素是否存在
    if (mySet.find(2) != mySet.end()) {
        std::cout << "Element 2 is in the set" << std::endl;
    } else {
        std::cout << "Element 2 is not in the set" << std::endl;
    }
/************************************************************************************/
// 创建一个 std::unordered_set
    std::unordered_set<int> mySet;

    // 插入元素
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(5);

    // 遍历 unordered_set
    for (const auto& elem : mySet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 检查元素是否存在
    if (mySet.find(2) != mySet.end()) {
        std::cout << "Element 2 is in the set" << std::endl;
    } else {
        std::cout << "Element 2 is not in the set" << std::endl;
    }

/************************************************************************************/
// 创建一个 std::multiset
    std::multiset<int> myMultiset;

    // 插入元素
    myMultiset.insert(3);
    myMultiset.insert(1);
    myMultiset.insert(5);
    myMultiset.insert(3); // 允许重复值

    // 遍历 multiset
    for (const auto& elem : myMultiset) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 检查元素个数
    std::cout << "Number of occurrences of 3: " << myMultiset.count(3) << std::endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值