【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;
    }
};
相关推荐
吾当每日三饮五升7 分钟前
C++单例模式跨DLL调用问题梳理
开发语言·c++·单例模式
猫武士水星38 分钟前
C++ scanf
开发语言·c++
捕鲸叉2 小时前
QT自定义工具条渐变背景颜色一例
开发语言·前端·c++·qt
Rossy Yan2 小时前
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
c++·排序算法·面向对象·封装·查找
wjm0410062 小时前
贪心算法概述
算法·贪心算法
我搞slam3 小时前
全覆盖路径规划算法之BCD源码实现(The Boustrophedon Cellular Decomposition)
c++·算法·图搜索算法
Rossy Yan3 小时前
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
开发语言·数据结构·c++·算法·查找·头歌实践教学平台·合集
埃菲尔铁塔_CV算法4 小时前
BOOST 在计算机视觉方面的应用及具体代码分析(二)
c++·人工智能·算法·机器学习·计算机视觉
Smark.4 小时前
(leetcode算法题)137. 只出现一次的数字 II
算法·leetcode
DB_UP4 小时前
基于XGBoost的集成学习算法
算法·机器学习·集成学习