【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序

目录

一、iota函数

1. 函数解析

​①  迭代器类型(补充)

② 头文件

③  参数

2. 函数用途与实例

二、sort函数

1、 函数解读

2、实现倒序排列

2.1 greater 与 less 模板参数

2.2  lambda表达式

三、下标绑定排序(zip) --- 833.字符串中的查找与替换


一、iota函数

1. 函数解析

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第1张图片①  迭代器类型(补充)

ForwardIterator :ForwardIterator为正向迭代器,它只支持加操作不支持减操作;

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第2张图片

② 头文件

#include       // std::iota

③  参数

first:第一个参数是指向区间中的第一个位置的迭代器

last:第二个参数是指向区间最后一个位置的后一个位置的迭代器,也就一个左闭右开的区间

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第3张图片

val:第三个参数传入区间第一个位置的值 

2. 函数用途与实例

将首元素为val,公差为1的连续递增序列依次分配给区间 [first, last) 

#include
#include
#include       // std::iota
int main()
{
	std::vector 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;
}

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第4张图片

二、sort函数

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第5张图片

 1、 函数解读

① 函数实现了默认升序对一个左闭右开的区间 [first, last) 进行排序

② 可通过仿函数重载operator< 或operator> 实现自定义数据排序

③ sort函数底层实现为快速排序,即为不稳定排序,等效元素相对位置可能会发生改变,若要实现稳定排序,可以使用stable_sort函数

2、实现倒序排列

2.1 greater 与 less 模板参数

#include
#include
#include     //sort函数的头文件
#include    //greater算法的头文件
int main()
{
	std::vector v = {3, 2, 6, 1, 8, 5, 2, 6};
	std::sort(v.begin(), v.end(), std::greater());
	for (auto x : v) std::cout << x << ' ';
	return 0;
}

2.2  lambda表达式

#include
#include
#include     //sort函数的头文件
#include  

using namespace std;
int main() {
	vector 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 的并行数组给出:indicessources,  targets

要完成第 i 个替换操作:

  1. 检查 子字符串  sources[i] 是否出现在 原字符串 s 的索引 indices[i] 处。
  2. 如果没有出现, 什么也不做 。
  3. 如果出现,则用 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:

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序_第6张图片

输入: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& indices, vector& sources, vector& targets) {
        int n = indices.size();

        vector 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& indices, vector& sources, vector& targets) {
        int n = indices.size();
        vector> zip;
        for (int i = 0; i < n; i++) zip.push_back({indices[i], sources[i], targets[i]});
        sort(zip.begin(), zip.end(), greater>());
        
        for (auto& [i, source, target] : zip) {    
            int len = source.length();
            if (s.substr(i, len) == source) {
                s.replace(i, len, target);
            }
        }
        return s;
    }
};

你可能感兴趣的:(C++,c++,算法)