本篇博客中 , 实现一个 set 集合 , 存放 英文字母 组成的字符串 , 且 大小写不敏感 ;
实现的方法 : 自定义字符串 对比排序规则 , 先 将 字符串 都转为小写字母 , 然后进行对比 ;
tolower 函数是 C / C++ 标准库 中的函数 , 其作用是 将 字符从 大写形式 转换为 小写形式 , 该函数定义在 C++ 头文件 的 <cctype> 中 或 C 语言头文件的 <ctype.h> 中 ;
tolower 函数原型如下 :
int tolower(int c);
注意 : 为了保证 tolower 函数的行为 的 稳定性 , 建议 先将 char 类型的参数转换为 unsigned char , 然后 再传递给 tolower 函数 ; 运行该程序的平台可能是 Windows / Linux , Arm / 单片机 平台 , 如果 char 在指定的平台上 被当作负数处理 , 直接传递给 tolower 可能会导致未定义的行为 ;
代码示例 :
#include "iostream"
using namespace std;
#include <algorithm>
int main() {
string hello = "Hello, World!";
// 将字符串中的所有字符元素转为小写字母
transform(hello.begin(), hello.end(), hello.begin(), tolower);
cout << hello << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
hello, world! Press any key to continue . . .
与 tolower 函数对象 相对的是 toupper 函数 , 可以将 字符 转为 大写形式 ;
toupper 函数原型如下 :
int toupper(int c);
代码示例 :
#include "iostream"
using namespace std;
#include <algorithm>
int main() {
string hello = "Hello, World!";
// 将字符串中的所有字符元素转为大写字母
transform(hello.begin(), hello.end(), hello.begin(), toupper);
cout << hello << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
HELLO, WORLD! Press any key to continue . . .
该 set 集合 的 比较函数 的 函数对象 , 是一个二元谓词 ,
重写的 函数调用操作符 函数如下 :
bool operator()(const string& str1, const string& str2)
接收 2 个 字符串 参数 ,
注意 : 比较的前提是 不能修改实参的值 , 这里重新创建 2 个字符串 , 用于 将 字符串转为 小节字母 并 进行比较 ;
首先 , 创建一个新的 字符串 对象 ;
// 创建字符串
string s1;
然后 , 根据 传入的 字符串参数大小 , 设置 新创建的字符串对象 ;
// 重新设置字符串大小
s1.resize(str1.size());
最后 , 调用 transform 算法 , 将 字符串 中的字符元素 , 都转为小写字母 ;
// 将字符串的所有元素都转换为小写元素
transform(str1.begin(), str1.end(), s1.begin(), tolower);
得到 全是 小写字母 的字符串 后 , 使用该 小写字母 字符串 与 另外一个参数 转成的 小写字母 字符串 进行对比 , 这样就实现了 大小写不敏感的 set 集合 ;
代码示例如下 :
#include <algorithm>
#include "functional"
/// <summary>
/// 二元谓词 大小写不敏感比较
/// </summary>
class Compare
{
public:
bool operator()(const string& str1, const string& str2) const
{
// 比较的前提是不能修改实参的值
// 这里重新创建 2 个字符串 , 用于进行比较
// 创建字符串
string s1;
// 重新设置字符串大小
s1.resize(str1.size());
// 将字符串的所有元素都转换为小写元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //预定义函数对象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //预定义函数对象
// 从小到大进行排序
return (s1 < s2);
}
};
创建普通的 set 集合 , 并插入三个元素 ;
// 创建一个 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
集合中的元素是
a b c
在集合中查找 字符串 " a " , 肯定能找到该元素 ;
代码示例 :
#include "iostream"
using namespace std;
#include <set>
#include <algorithm>
int main() {
// 创建一个 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循环中传入 Lambda 表达式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("a"); //find函数 默认 区分大小写
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "没有找到元素" << endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
a b c
找到了元素
Press any key to continue . . .
创建普通的 set 集合 , 并插入三个元素 ;
// 创建一个 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
集合中的元素是
a b c
在集合中查找 字符串 " A " , 找不到该元素 ;
代码示例 :
#include "iostream"
using namespace std;
#include <set>
#include <algorithm>
int main() {
// 创建一个 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循环中传入 Lambda 表达式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("A"); //find函数 默认 区分大小写
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "没有找到元素" << endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
a b c
没有找到元素
Press any key to continue . . .
在下面的代码中 , 创建 set 集合时 , 指定了 集合元素的 排序规则 :
// 创建一个 set 集合容器
set<string, Compare> mySet;
该 Compare 排序规则 是一个 二元谓词 , 在排序时 , 将字符串先转为 小写字母 , 然后进行排序 ;
/// <summary>
/// 二元谓词 大小写不敏感比较
/// </summary>
class Compare
{
public:
bool operator()(const string& str1, const string& str2) const
{
// 比较的前提是不能修改实参的值
// 这里重新创建 2 个字符串 , 用于进行比较
// 创建字符串
string s1;
// 重新设置字符串大小
s1.resize(str1.size());
// 将字符串的所有元素都转换为小写元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //预定义函数对象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //预定义函数对象
// 从小到大进行排序
return (s1 < s2);
}
};
在排序时 , 大小写字母不敏感 , 即使是大写字母 " A " , 也会当做 " a " 进行排序 ;
查找元素时 , 查找 " A " 字符串 , 实际上查找的是 " a " 字符串 ;
使用 find 函数 查找元素时 , 可以找到 " A " 元素 ;
代码示例 :
#include "iostream"
using namespace std;
#include <set>
#include <algorithm>
#include "functional"
/// <summary>
/// 二元谓词 大小写不敏感比较
/// </summary>
class Compare
{
public:
bool operator()(const string& str1, const string& str2) const
{
// 比较的前提是不能修改实参的值
// 这里重新创建 2 个字符串 , 用于进行比较
// 创建字符串
string s1;
// 重新设置字符串大小
s1.resize(str1.size());
// 将字符串的所有元素都转换为小写元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //预定义函数对象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //预定义函数对象
// 从小到大进行排序
return (s1 < s2);
}
};
int main() {
// 创建一个 set 集合容器
set<string, Compare> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循环中传入 Lambda 表达式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("A"); //find函数 默认 区分大小写
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "没有找到元素" << endl;
}
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
a b c
找到了元素
Press any key to continue . . .