从零开始的Cpp(5)集合set与unorder_set与三元表达式

1.Set

set是一个有序的集合,其中的元素是唯一的,不允许重复(这可以实现并集的操作)。

它基于红黑树实现,因此插入、删除和查找操作都具有较高的效率。没有索引。

元素会按照升序排序,默认情况下,也可以自定义排序规则。

set的主要操作:

下面是set类的主要操作:

插入元素:可以使用insert()函数将一个元素插入到set中,并将其自动排序。

删除元素:可以使用erase()函数删除 

查找元素:可以使用find()函数来查找指定的元素,返回值是一个指向该元素的迭代器。如果元素不存在,则返回end()迭代器。

获取元素个数:可以使用size()函数获取set中的元素个数。

清空整个set:可以使用clear()函数清空整个set

下面用一段程序体现set的主要功能:

#include <iostream>
#include <set>

int main() {
    std::set<int> mySet;

    // 插入元素
    mySet.insert(5);
    mySet.insert(2);
    mySet.insert(8);
    mySet.insert(2); // 重复元素不会被插入

    // 遍历并输出所有元素
    std::cout << "Elements in set: ";
    for (int i : mySet) {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    // 查找元素
    int key = 8;
    std::set<int>::iterator it = mySet.find(key);
    if (it != mySet.end()) {
        std::cout << key << " found in set." << std::endl;
    } else {
        std::cout << key << " not found in set." << std::endl;
    }

    // 删除元素
    mySet.erase(2);

    // 遍历并输出所有元素
    std::cout << "Elements in set after erasing: ";
    for (int i : mySet) {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    return 0;
}

在上面的示例中,我们首先创建了一个空的set容器 `mySet`。然后,我们使用 `insert` 函数插入元素 5、2 和 8。由于set容器中的元素是唯一的,所以重复的元素(如插入的第二个2)不会被插入。

接下来,我们使用范围 `for` 循环遍历并输出所有元素。由于set是有序的,所以输出的元素会按照升序排序。

然后,我们使用 `find` 函数查找元素 8 是否在set中。如果找到了,我们输出该元素存在于set中的信息;如果没有找到,我们输出该元素不存在于set中的信息。

最后,我们使用 `erase` 函数删除元素 2。然后再次遍历并输出所有元素,可以看到元素 2 已经被成功删除。

交集,并集,差集

`set` 支持集合操作,包括交集、并集和差集。可以使用 `set` 的成员函数或算法库中的函数来实现这些操作。

下面是使用 `set` 的成员函数实现集合操作的示例代码:

#include <iostream>
#include <set>

int main() {
    std::set<int> set1 = { 1, 2, 3, 4, 5 };
    std::set<int> set2 = { 3, 4, 5, 6, 7 };

    // 交集
    std::set<int> intersection;
    for (auto element : set1) {
        if (set2.count(element) > 0) {
            intersection.insert(element);
        }
    }

    // 并集
    std::set<int> unionSet = set1;
    unionSet.insert(set2.begin(), set2.end());

    // 差集
    std::set<int> difference;
    for (auto element : set1) {
        if (set2.count(element) == 0) {
            difference.insert(element);
        }
    }

    // 输出结果
    std::cout << "Intersection: ";
    for (auto element : intersection) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    std::cout << "Union: ";
    for (auto element : unionSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    std::cout << "Difference: ";
    for (auto element : difference) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果为:

Intersection: 3 4 5

Union: 1 2 3 4 5 6 7

Difference: 1 2

上述代码中,我们使用了 `count()` 成员函数来判断元素是否存在于另一个集合中。然后,根据判断结果,将元素插入到相应的集合中,从而实现了交集、并集和差集的操作。

除了使用成员函数,还可以使用算法库中的函数来实现集合操作,如 `std::set_intersection()`、`std::set_union()` 和 `std::set_difference()` 等。这些函数的使用方式与上述示例类似,只是需要传入迭代器范围作为参数,并指定输出结果的目标容器。

`std::set_intersection()`、`std::set_union()` 和 `std::set_difference()` 是 C++ 标准库中的算法函数,用于实现集合操作。这些函数位于 `<algorithm>` 头文件中。

下面是使用这些函数实现集合操作的示例代码:

#include <iostream>
#include <algorithm>
#include <set>

int main() {
    std::set<int> set1 = { 1, 2, 3, 4, 5 };
    std::set<int> set2 = { 3, 4, 5, 6, 7 };

    // 交集
    std::set<int> intersection;
    std::set_intersection(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(intersection));

    // 并集
    std::set<int> unionSet;
    std::set_union(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(unionSet));

    // 差集
    std::set<int> difference;
    std::set_difference(set1.begin(), set1.end(), set2.begin(), set2.end(), std::back_inserter(difference));

    // 输出结果
    std::cout << "Intersection: ";
    for (const auto& element : intersection) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    std::cout << "Union: ";
    for (const auto& element : unionSet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    std::cout << "Difference: ";
    for (const auto& element : difference) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

输出结果与前面的示例相同:

Intersection: 3 4 5

Union: 1 2 3 4 5 6 7

Difference: 1 2

在上述代码中,我们使用了 `std::set_intersection()`、`std::set_union()` 和 `std::set_difference()` 函数来进行集合操作。这些函数接受四个迭代器参数,分别表示两个集合的起始和结束位置。需要注意的是,输出结果需要提供一个目标容器,我们使用 `std::back_inserter()` 来将结果插入到一个 `std::vector` 容器中。

通过使用这些算法函数,我们可以更简洁地实现集合操作,而不需要手动编写循环来遍历集合元素。

 2.unorder_set

`unordered_set`是C++标准库中的一个容器,它提供了一种无序、唯一的元素集合。它基于哈希表实现,因此具有快速的插入、查找和删除操作的特点。

与`set`相比,`unordered_set`不会对元素进行排序,而是根据元素的哈希值进行组织和存储。这使得在大多数情况下,`unordered_set`的插入、查找和删除操作的时间复杂度都是常数级别的,即O(1)。

`unordered_set`的常用操作:

下面是unorder_set类的主要操作:

插入元素:可以使用insert()函数将一个元素插入到unorder_set中。

删除元素:可以使用erase()函数删除 

查找元素:可以使用find()函数来查找指定的元素,返回值是一个指向该元素的迭代器。如果元素不存在,则返回end()迭代器。

获取元素个数:可以使用size()函数获取set中的元素个数。

清空整个set:可以使用clear()函数清空整个set

用一段代码展示unorder_set的主要功能:


#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> mySet;

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

    // 删除元素
    mySet.erase(2);

    // 查找元素
    auto it = mySet.find(3);
    if (it != mySet.end()) {
        std::cout << "Found element: " << *it << std::endl;
    }

    // 遍历元素
    for (auto element : mySet) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    // 获取大小和容量
    std::cout << "Size: " << mySet.size() << std::endl;
    std::cout << "Empty: " << (mySet.empty() ? "true" : "false") << std::endl;

    return 0;
}

输出结果:

Found element: 3

1 3

Size: 2

Empty: false

`unordered_set`和`set`

`unordered_set`和`set`是C++标准库中的两种不同的容器,它们在实现方式、性能和用途上有一些区别。

1. 实现方式:

   - `unordered_set`:基于哈希表实现,使用哈希函数将元素映射到桶中,具有快速的插入、查找和删除操作。

   - `set`:基于红黑树实现,对元素进行排序并保持唯一性,具有自动排序的特性。

2. 元素顺序:

   - `unordered_set`:不会对元素进行排序,元素存储的顺序是根据哈希值决定的,因此是无序的。

   - `set`:会根据元素的比较函数进行排序,元素存储的顺序是有序的。

3. 插入和查找性能:

   - `unordered_set`:插入、查找和删除操作的平均时间复杂度为常数级别O(1),但在最坏情况下可能达到线性级别O(n)。

   - `set`:插入、查找和删除操作的平均时间复杂度为对数级别O(log n),保持了较好的性能。

4. 内存占用:

   - `unordered_set`:由于使用哈希表,需要额外的内存来存储桶和哈希函数等信息,因此在相同元素数量的情况下,通常会占用更多的内存。

   - `set`:由于使用红黑树,不需要额外的内存来存储哈希表等信息,因此在相同元素数量的情况下,通常会占用较少的内存。

 3.三元表达式

在之前的代码里,我们用到了三元表达式:

mySet.empty() ? "true" : "false"

在C++中,a?b: c 是三元条件运算符(也称为三元表达式)。它的功能是根据条件 a 的结果来选择执行 b 还是 c。
具体来说,如果条件 a 为真(非零),则表达式的结果为 b;如果条件 a 为假(零),则表达式的结果为 c。因此,三元条件运算符可以看作是一个简洁的if-else语句的缩写形式。
例如,以下代码使用三元条件运算符来比较两个整数的大小,并输出较大的数:
 

int a = 10;
int b = 20;
int maxNum = (a > b) ? a : b;
std::cout << "The maximum number is: " << maxNum << std::endl;



在上述代码中,如果 a 大于 b,则将 a 的值赋给 maxNum;否则,将 b 的值赋给 maxNum。最后,通过输出语句将结果打印到控制台。
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值