一、二元謂詞使用場景 - 大小寫不敏感 set 集合
1、需求分析
本篇博客中 , 實現(xiàn)一個 set 集合 , 存放 英文字母 組成的字符串 , 且 大小寫不敏感 ;
實現(xiàn)的方法 : 自定義字符串 對比排序規(guī)則 , 先 將 字符串 都轉(zhuǎn)為小寫字母 , 然后進行對比 ;
2、tolower 函數(shù) - 將字符轉(zhuǎn)為小寫字母
tolower 函數(shù)是 C / C++ 標(biāo)準(zhǔn)庫 中的函數(shù) , 其作用是 將 字符從 大寫形式 轉(zhuǎn)換為 小寫形式 , 該函數(shù)定義在 C++ 頭文件 的 <cctype> 中 或 C 語言頭文件的 <ctype.h> 中 ;
- 如果傳入的 字符 是 大寫字母 , 將 該大寫字母 轉(zhuǎn)為小寫字母 并返回 ;
- 如果傳入的 字符 是 小寫字母 , 將 該小寫字母 直接返回 ;
tolower 函數(shù)原型如下 :
int tolower(int c);
-
參數(shù)解析 : 參數(shù) c 表示字符的 int 類型的值 ;
- char -> int 類型轉(zhuǎn)換 : 參數(shù)中使用了 int 類型值 , 一般情況下此處應(yīng)該傳入一個 char 類型的值 , 該 字符 會被隱式地轉(zhuǎn)換為 int 類型 ;
- 傳入的值需要 在 [ CHAR_MIN , CHAR_MAX ] 區(qū)間 中 , 或者 是 EOF ( -1 ) 值 ;
- 返回值解析 : 如果 參數(shù) c 是 大寫字母 , 則返回對應(yīng)的小寫字母 ; 否則 , 返回 c 字符本身 ; 返回值是 int 類型的 , 但通??梢园踩貙⑵滢D(zhuǎn)換回 char 類型 ;
注意 : 為了保證 tolower 函數(shù)的行為 的 穩(wěn)定性 , 建議 先將 char 類型的參數(shù)轉(zhuǎn)換為 unsigned char , 然后 再傳遞給 tolower 函數(shù) ; 運行該程序的平臺可能是 Windows / Linux , Arm / 單片機 平臺 , 如果 char 在指定的平臺上 被當(dāng)作負(fù)數(shù)處理 , 直接傳遞給 tolower 可能會導(dǎo)致未定義的行為 ;
代碼示例 :
#include "iostream"
using namespace std;
#include <algorithm>
int main() {
string hello = "Hello, World!";
// 將字符串中的所有字符元素轉(zhuǎn)為小寫字母
transform(hello.begin(), hello.end(), hello.begin(), tolower);
cout << hello << endl;
// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
hello, world!
Press any key to continue . . .
3、toupper 函數(shù) - 將字符轉(zhuǎn)為大寫字母
與 tolower 函數(shù)對象 相對的是 toupper 函數(shù) , 可以將 字符 轉(zhuǎn)為 大寫形式 ;
toupper 函數(shù)原型如下 :
int toupper(int c);
-
參數(shù)解析 : 參數(shù) c 表示字符的 int 類型的值 ;
- char -> int 類型轉(zhuǎn)換 : 參數(shù)中使用了 int 類型值 , 一般情況下此處應(yīng)該傳入一個 char 類型的值 , 該 字符 會被隱式地轉(zhuǎn)換為 int 類型 ;
- 傳入的值需要在 [ CHAR_MIN , CHAR_MAX ] 區(qū)間 中 , 或者是 EOF ( -1 ) 值 ;
- 返回值解析 : 如果參數(shù) c 是 小寫字母 , 則返回對應(yīng)的大寫字母 ; 否則 , 返回 c 字符本身 ; 返回值是 int 類型的 , 但通??梢园踩貙⑵滢D(zhuǎn)換回 char 類型 ;
代碼示例 :
#include "iostream"
using namespace std;
#include <algorithm>
int main() {
string hello = "Hello, World!";
// 將字符串中的所有字符元素轉(zhuǎn)為大寫字母
transform(hello.begin(), hello.end(), hello.begin(), toupper);
cout << hello << endl;
// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
HELLO, WORLD!
Press any key to continue . . .
4、基于 tolower 實現(xiàn)大小寫不敏感的比較函數(shù)對象
該 set 集合 的 比較函數(shù) 的 函數(shù)對象 , 是一個二元謂詞 ,
重寫的 函數(shù)調(diào)用操作符 函數(shù)如下 :
bool operator()(const string& str1, const string& str2)
接收 2 個 字符串 參數(shù) ,
注意 : 比較的前提是 不能修改實參的值 , 這里重新創(chuàng)建 2 個字符串 , 用于 將 字符串轉(zhuǎn)為 小節(jié)字母 并 進行比較 ;
首先 , 創(chuàng)建一個新的 字符串 對象 ;
// 創(chuàng)建字符串
string s1;
然后 , 根據(jù) 傳入的 字符串參數(shù)大小 , 設(shè)置 新創(chuàng)建的字符串對象 ;
// 重新設(shè)置字符串大小
s1.resize(str1.size());
最后 , 調(diào)用 transform 算法 , 將 字符串 中的字符元素 , 都轉(zhuǎn)為小寫字母 ;
// 將字符串的所有元素都轉(zhuǎn)換為小寫元素
transform(str1.begin(), str1.end(), s1.begin(), tolower);
得到 全是 小寫字母 的字符串 后 , 使用該 小寫字母 字符串 與 另外一個參數(shù) 轉(zhuǎn)成的 小寫字母 字符串 進行對比 , 這樣就實現(xiàn)了 大小寫不敏感的 set 集合 ;
代碼示例如下 :
#include <algorithm>
#include "functional"
/// <summary>
/// 二元謂詞 大小寫不敏感比較
/// </summary>
class Compare
{
public:
bool operator()(const string& str1, const string& str2) const
{
// 比較的前提是不能修改實參的值
// 這里重新創(chuàng)建 2 個字符串 , 用于進行比較
// 創(chuàng)建字符串
string s1;
// 重新設(shè)置字符串大小
s1.resize(str1.size());
// 將字符串的所有元素都轉(zhuǎn)換為小寫元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //預(yù)定義函數(shù)對象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //預(yù)定義函數(shù)對象
// 從小到大進行排序
return (s1 < s2);
}
};
二、代碼示例 - 二元謂詞使用場景
1、普通的 set 集合查找元素 - 大小寫匹配查找成功
創(chuàng)建普通的 set 集合 , 并插入三個元素 ;
// 創(chuàng)建一個 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() {
// 創(chuàng)建一個 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循環(huán)中傳入 Lambda 表達式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("a"); //find函數(shù) 默認(rèn) 區(qū)分大小寫
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "沒有找到元素" << endl;
}
// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
a b c
找到了元素
Press any key to continue . . .
2、普通的 set 集合查找元素 - 大小寫不匹配查找失敗
創(chuàng)建普通的 set 集合 , 并插入三個元素 ;
// 創(chuàng)建一個 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() {
// 創(chuàng)建一個 set 集合容器
set<string> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循環(huán)中傳入 Lambda 表達式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("A"); //find函數(shù) 默認(rèn) 區(qū)分大小寫
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "沒有找到元素" << endl;
}
// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :
a b c
沒有找到元素
Press any key to continue . . .
3、設(shè)置二元謂詞規(guī)則的 set 集合查找元素 - 大小寫不不敏感集合
在下面的代碼中 , 創(chuàng)建 set 集合時 , 指定了 集合元素的 排序規(guī)則 :
// 創(chuàng)建一個 set 集合容器
set<string, Compare> mySet;
該 Compare 排序規(guī)則 是一個 二元謂詞 , 在排序時 , 將字符串先轉(zhuǎn)為 小寫字母 , 然后進行排序 ;
/// <summary>
/// 二元謂詞 大小寫不敏感比較
/// </summary>
class Compare
{
public:
bool operator()(const string& str1, const string& str2) const
{
// 比較的前提是不能修改實參的值
// 這里重新創(chuàng)建 2 個字符串 , 用于進行比較
// 創(chuàng)建字符串
string s1;
// 重新設(shè)置字符串大小
s1.resize(str1.size());
// 將字符串的所有元素都轉(zhuǎn)換為小寫元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //預(yù)定義函數(shù)對象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //預(yù)定義函數(shù)對象
// 從小到大進行排序
return (s1 < s2);
}
};
在排序時 , 大小寫字母不敏感 , 即使是大寫字母 " A " , 也會當(dāng)做 " a " 進行排序 ;
查找元素時 , 查找 " A " 字符串 , 實際上查找的是 " a " 字符串 ;
使用 find 函數(shù) 查找元素時 , 可以找到 " 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
{
// 比較的前提是不能修改實參的值
// 這里重新創(chuàng)建 2 個字符串 , 用于進行比較
// 創(chuàng)建字符串
string s1;
// 重新設(shè)置字符串大小
s1.resize(str1.size());
// 將字符串的所有元素都轉(zhuǎn)換為小寫元素
transform(str1.begin(), str1.end(), s1.begin(), tolower); //預(yù)定義函數(shù)對象
string s2;
s2.resize(str2.size());
transform(str2.begin(), str2.end(), s2.begin(), tolower); //預(yù)定義函數(shù)對象
// 從小到大進行排序
return (s1 < s2);
}
};
int main() {
// 創(chuàng)建一個 set 集合容器
set<string, Compare> mySet;
// 向容器中插入元素
mySet.insert("b");
mySet.insert("a");
mySet.insert("c");
// 向 foreach 循環(huán)中傳入 Lambda 表達式
for_each(mySet.begin(), mySet.end(), [](string str) {
std::cout << str << " ";
});
cout << endl;
// 查找容器中的元素
set<string>::iterator it = mySet.find("A"); //find函數(shù) 默認(rèn) 區(qū)分大小寫
if (it != mySet.end()) {
cout << "找到了元素" << endl;
} else {
cout << "沒有找到元素" << endl;
}
// 控制臺暫停 , 按任意鍵繼續(xù)向后執(zhí)行
system("pause");
return 0;
};
執(zhí)行結(jié)果 :文章來源:http://www.zghlxwxcb.cn/news/detail-782153.html
a b c
找到了元素
Press any key to continue . . .
文章來源地址http://www.zghlxwxcb.cn/news/detail-782153.html
到了這里,關(guān)于【C++】STL 算法 ⑦ ( 二元謂詞使用場景 - 大小寫不敏感 set 集合 | tolower 函數(shù) - 將字符轉(zhuǎn)為小寫字母 | 基于 tolower 實現(xiàn)大小寫不敏感的比較函數(shù)對象 )的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!