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

目录

一、iota函数

[1. 函数解析](#1. 函数解析)

[​① 迭代器类型(补充)](#① 迭代器类型(补充))

[② 头文件](#② 头文件)

[③ 参数](#③ 参数)

[2. 函数用途与实例](#2. 函数用途与实例)

二、sort函数

[1、 函数解读](#1、 函数解读)

2、实现倒序排列

[2.1 greater 与 less 模板参数](#2.1 greater 与 less 模板参数)

[2.2 lambda表达式](#2.2 lambda表达式)

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


一、iota函数

1. 函数解析

① 迭代器类型(补充)

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

② 头文件

#include <numeric> // std::iota

③ 参数

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

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

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

2. 函数用途与实例

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

cpp 复制代码
#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 模板参数

cpp 复制代码
#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表达式

cpp 复制代码
#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 个替换操作:

  1. 检查 子字符串 sources[i] 是否出现在 原字符串 s 的索引 indices[i] 处。
  2. 如果没有出现, 什么也不做
  3. 如果出现,则用 targets[i] 替换 该子字符串。

例如,如果 s = "abcd"indices[i] = 0 , sources[i] = "ab"targets[i] = "eee" ,那么替换的结果将是 "++eee++cd"

所有替换操作必须 同时 发生,这意味着替换操作不应该影响彼此的索引。测试用例保证元素间不会重叠

  • 例如,一个 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的值进行倒序排列;

cpp 复制代码
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]倒序排列

cpp 复制代码
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;
    }
};
相关推荐
学地理的小胖砸37 分钟前
【高分系列卫星简介】
开发语言·数码相机·算法·遥感·地理信息
码农豆豆39 分钟前
4.C++中程序中的命名空间
开发语言·c++
Joker1008540 分钟前
C++初阶学习——探索STL奥秘——标准库中的priority_queue与模拟实现
c++
怀九日42 分钟前
C++(学习)2024.9.19
开发语言·c++·学习·重构·对象·
KookeeyLena81 小时前
如何限制任何爬虫爬取网站的图片
开发语言·c++·爬虫
m_Molly1 小时前
vs2022配置opencv==4.9.0(C++)
c++·opencv
yanyanwenmeng1 小时前
matlab基础
开发语言·算法·matlab
##晴天小猪1 小时前
ByteTrack多目标跟踪流程图
人工智能·算法·目标检测·机器学习·目标跟踪
charon87781 小时前
Unreal Engine 5 C++: 编辑器工具编写入门(中文解释)
c++·ue5·编辑器·游戏引擎·虚幻
Ddddddd_1581 小时前
C++ | Leetcode C++题解之第421题数组中两个数的最大异或值
c++·leetcode·题解