【日常学习】【语法】STL之set

本文介绍了如何利用C++标准库中的Set数据结构来实现文本中单词的字典序排序,并确保每个单词仅出现一次。文章通过一个具体的UVa在线编程题目示例详细展示了Set的基本操作,包括插入元素、遍历输出等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天刚刚学习了set 在我写这篇文章之前 请允许我首先对TY菌表示诚挚的感激 请教TY菌之前我眼里ruka简直不知所云TUT

set是一个集合 和康托前辈的一样 集合中的元素不重复 且集合中的元素是有序的(自动有序化) TY菌介绍说其内部实质是一个平衡树

set不是数组 只能通过迭代器(iterator)把里面的元素倒出来 迭代器相当于是指针 扫描的是地址 因此输出的时候需要用*variation


声明:

需要用到头文件set

set<string> dict; 建立一个集合 其名为dict 基类型是string


常用函数:

dict.insert() 将括号里的变量放到集合中

dict.begin() dict.end()返回集合最初和最后的元素的地址

这是写这个例题用到的


在某书的最后函数附录里看到这些好像都是list模板函数 暂时还不清楚是怎么回事  

这次例题是Uva10815 - Andy's First Dictionary 安迪的第一个字典 大意是给你一段文字 把里面的单词按字典序排列 每个单词只出现一次

先放代码

#include<iostream>
#include<string>
#include<set>
#include<sstream>
using namespace std;

set<string> dict;//set up a set called dict-short for dictionary,and it's based on string type;

int main(){
	string s,buf;
	while (cin>>s){
		for (int i=0;i<s.length();i++)
		  if (isalpha(s[i])) s[i]=tolower(s[i]);//if it's an letter,turn it lowercase.Others turn space and use stringstream to leave it out=ignore it
		  else s[i]=' ';
		stringstream ss(s);
		while (ss>>buf) dict.insert(buf);//insert it into the set which is already in order,TYkon said it's a balanced tree inside
	}
	for (set<string>::iterator it=dict.begin();it!=dict.end();++it)//iterator just like a point,scan it from beginning to end and output
	  cout<<*it<<endl;//NOTICE output by point
	return 0;
}
还是英文注释不过看懂应该问题不大

isalpha()判断是否是字母 如果是就用头tolower()转换成小写 否则就转为空格 这样是为了字符串流重读入的时候能够把空格去掉

特别强调一下本例中出现的迭代器

for (set<string>::iterator it=dict.begin();it!=dict.end();++it)//iterator just like a point,scan it from beginning to end and output
	  cout<<*it<<endl;//NOTICE output by point

迭代器iterator相当于是个类型 it是一个变量 基类型是iterator 它从开始扫到结尾的前一个【据TY菌解释 像数组一样 最后一位是没有值的 数组是一个结束标志 不知集合最后是什么】输出的时候 由于it扫描的是地址 要输出*it


显然对于set我还知之甚少 还需要在今后的学习中不断掌握

这个寒假又是一个繁忙的寒假 希望我在这个短暂仓促却又温暖充实的假期中能长进良多 


—— 渐黄昏,清角吹寒,都在空城

<think>好的,我现在要解决用户的问题,关于C++ STLset容器的访问方法和示例。首先,我需要回忆一下set的基本特性。set是一个有序的关联容器,存储唯一元素,按特定排序准则自动排序。用户想知道如何访问其中的元素,需要给出方法并示例。 首先,访问set元素的方法有哪些呢?常见的遍历方法包括范围for循环和迭代器。另外,查找特定元素可以用find或者count。不过要注意,set没有下标操作符,不能像vector那样随机访问。 接下来,根据用户提供的引用内容,引用[1]中提到了范围for循环和迭代器遍历的示例代码,比如for (int elem : mySet)和使用begin()/end()的迭代器。这应该是两种主要的访问方式。此外,引用[2]提到set_union和ostream_iterator输出元素,这可能涉及到算法库中的方法,但用户的问题主要是访问,所以可能不需要深入这部分。 然后,需要确保回答的结构清晰,分点说明每种方法,并给出对应的代码示例。例如,分点说明范围循环、迭代器、反向迭代器、查找元素等。同时要注意用户提到的引用,在适当的地方添加引用标识,比如在提到范围for循环时引用[^1]。 另外,用户可能还关心如何判断元素是否存在,可以使用count或者find方法,比如count返回0或1,find返回迭代器。这部分在引用[3]中提到了count和equal_range,虽然equal_range可能在multiset中更有用,但在set中也可以使用,但可能用户更需要基础的访问方法。 需要注意的是,set的元素是只读的,不能通过迭代器修改,否则会破坏内部的有序结构。所以在示例代码中要强调这一点,比如在迭代器遍历时,*it是const的,不能修改。 最后,生成相关问题,考虑用户可能进一步想知道性能问题、其他容器对比或者应用场景,比如为什么选择set而不是unordered_set,或者如何高效地查找元素等。 检查是否有遗漏的方法,比如使用全局函数如std::begin和std::end,或者C++11之后的auto关键字简化迭代器声明。确保所有代码示例正确,符合C++标准,特别是引用中的代码是否存在问题。例如,引用[1]中的代码使用了auto it = mySet.begin(),这是正确的,并且用*it访问元素。 总结回答的结构:先介绍set的特点,然后分点列出访问方法,每种方法给出示例代码,并引用对应的引用来源。最后添加相关问题。</think>在 C++ STL 中,`set` 容器是一个有序且元素唯一的关联容器,访问其元素的方法主要有以下几种,均需遵循其**只读特性**(不可通过迭代器修改元素值): --- ### 1. **范围 for 循环遍历** 直接遍历所有元素,语法简洁(C++11 及以上支持): ```cpp #include <set> #include <iostream> int main() { std::set<int> mySet = {10, 20, 30}; for (const auto& elem : mySet) { // 使用 const 引用避免拷贝 std::cout << elem << " "; // 输出:10 20 30 } return 0; } ``` > 特点:无需手动处理迭代器[^1]。 --- ### 2. **迭代器遍历** 使用正向/反向迭代器访问元素: ```cpp // 正向迭代器(默认升序) for (auto it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *it << " "; // 通过解引用获取值 } // 反向迭代器(从末尾到开头) for (auto rit = mySet.rbegin(); rit != mySet.rend(); ++rit) { std::cout << *rit << " "; // 输出:30 20 10(若原set为{10,20,30}) } ``` > 注意:迭代器类型为 `std::set<T>::const_iterator`,禁止通过迭代器修改元素。 --- ### 3. **查找特定元素** 使用 `find()` 或 `count()` 定位元素: ```cpp auto it = mySet.find(20); if (it != mySet.end()) { // 检查是否存在 std::cout << "Found: " << *it; // 输出:Found: 20 } if (mySet.count(30) > 0) { // count返回0或1(set元素唯一) std::cout << "30 exists"; } ``` > 性能:基于红黑树实现,查找时间复杂度为 $O(\log n)$[^3]。 --- ### 4. **通过算法库输出元素** 结合 `std::copy` 和流迭代器批量输出: ```cpp #include <iterator> #include <algorithm> std::copy(mySet.begin(), mySet.end(), std::ostream_iterator<int>(std::cout, " ")); ``` > 适用于快速输出全部元素[^2]。 --- ### 注意事项 - **元素只读**:任何修改元素的操作(如 `*it = new_value`)会导致编译错误。 - **有序性**:遍历时元素按排序规则(默认升序)输出。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值