目录
一、iota函数
1. 函数解析
① 迭代器类型(补充)
② 头文件
③ 参数
2. 函数用途与实例
二、sort函数
1、 函数解读
2、实现倒序排列
2.1 greater 与 less 模板参数
2.2 lambda表达式
三、下标绑定排序(zip) --- 833.字符串中的查找与替换
一、iota函数
1. 函数解析
① 迭代器类型(补充)
ForwardIterator :ForwardIterator为正向迭代器,它只支持加操作不支持减操作;
② 头文件
#include <numeric> // std::iota
③ 参数
first:第一个参数是指向区间中的第一个位置的迭代器
last:第二个参数是指向区间最后一个位置的后一个位置的迭代器,也就一个左闭右开的区间
val:第三个参数传入区间第一个位置的值
2. 函数用途与实例
将首元素为val,公差为1的连续递增序列依次分配给区间 [first, last)
#include<iostream>
#include<vector>
#include <numeric> // std::iota
int main()
{
std::vector<int> v(10);
//分别将 0 1 2 3 4 5 6 7 8 9 填入区间 [ v.begin(), v.end() )
std::iota(v.begin(), v.end(), 0);
for (auto x : v) std::cout << x << ' ';
std::cout << std::endl;
int arr[10];
std::iota(arr, arr + 10, 0);
for (auto x : arr) std::cout << x << ' ';
return 0;
}
二、sort函数
1、 函数解读
① 函数实现了默认升序对一个左闭右开的区间 [first, last) 进行排序
② 可通过仿函数重载operator< 或operator> 实现自定义数据排序
③ sort函数底层实现为快速排序,即为不稳定排序,等效元素相对位置可能会发生改变,若要实现稳定排序,可以使用stable_sort函数
2、实现倒序排列
2.1 greater 与 less 模板参数
#include<iostream>
#include<vector>
#include<algorithm> //sort函数的头文件
#include<functional> //greater算法的头文件
int main()
{
std::vector<int> v = {3, 2, 6, 1, 8, 5, 2, 6};
std::sort(v.begin(), v.end(), std::greater<int>());
for (auto x : v) std::cout << x << ' ';
return 0;
}
2.2 lambda表达式
#include<iostream>
#include<vector>
#include<algorithm> //sort函数的头文件
#include <numeric>
using namespace std;
int main() {
vector<int> id(10);
// 0 1 2 3 4 5 6 7 8 9
iota(id.begin(), id.end(), 0);
// 9 8 7 6 5 4 3 2 1 0
sort(id.begin(), id.end(), [&](int i, int j) {return id[i] > id[j]; });
for (auto x : id) cout << x;
return 0;
}
三、下标绑定排序(zip) --- 833.字符串中的查找与替换
你会得到一个字符串
s
(索引从 0 开始),你必须对它执行k
个替换操作。替换操作以三个长度均为k
的并行数组给出:indices
,sources
,targets
。要完成第
i
个替换操作:
- 检查 子字符串
sources[i]
是否出现在 原字符串s
的索引indices[i]
处。- 如果没有出现, 什么也不做 。
- 如果出现,则用
targets[i]
替换 该子字符串。例如,如果
s = "abcd"
,indices[i] = 0
,sources[i] = "ab"
,targets[i] = "eee"
,那么替换的结果将是"eeecd"
。所有替换操作必须 同时 发生,这意味着替换操作不应该影响彼此的索引。测试用例保证元素间不会重叠 。
- 例如,一个
s = "abc"
,indices = [0,1]
,sources = ["ab","bc"]
的测试用例将不会生成,因为"ab"
和"bc"
替换重叠。在对
s
执行所有替换操作后返回 结果字符串 。子字符串 是字符串中连续的字符序列。
示例 1:
输入:s = "abcd", indices = [0,2], sources = ["a","cd"], targets = ["eee","ffff"] 输出:"eeebffff" 解释: "a" 从 s 中的索引 0 开始,所以它被替换为 "eee"。 "cd" 从 s 中的索引 2 开始,所以它被替换为 "ffff"。
解题思路:由于前面的字符替换可能使字符串下标发生改变,所以考虑从后往前替换字符串s,即从大到小遍历indices的数,并将下标从indices[i]开始长度为sources[i].size()的s的字串与sources[i]比较,若相等,则特换成targets[i]
法一 下标数组:
为实现从大到小遍历indices的数,若直接用sort函数排序,那么原本的indices[i]就不对应sources[i]了,我们可以通过定义indices的下标数组,在以indices的值进行倒序排列;
class Solution {
public:
string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {
int n = indices.size();
vector<int> id(n);
iota(id.begin(), id.end(), 0);
sort(id.begin(), id.end(), [&](int i, int j) {return indices[i] > indices[j];});
for (auto i : id) { //i为indices倒序之后的下标
int j = indices[i], len = sources[i].size();
if (s.substr(j, len) == sources[i]) {
s.replace(j, len, targets[i]);
}
}
return s;
}
};
法二 tuple:
直接将indices[i], sources[i], targets[i]通过tuple“打包”,再通过indices[i]倒序排列
class Solution {
public:
string findReplaceString(string s, vector<int>& indices, vector<string>& sources, vector<string>& targets) {
int n = indices.size();
vector<tuple<int, string, string>> zip;
for (int i = 0; i < n; i++) zip.push_back({indices[i], sources[i], targets[i]});
sort(zip.begin(), zip.end(), greater<tuple<int, string, string>>());
for (auto& [i, source, target] : zip) {
int len = source.length();
if (s.substr(i, len) == source) {
s.replace(i, len, target);
}
}
return s;
}
};