算法之旅,直奔<algorithm>之十六 find_end

本文详细介绍了 C++ 标准库中 find_end 函数的使用方法,该函数用于从后向前查找指定序列在数据集中的末次出现位置。通过具体示例展示了如何运用 find_end 进行数据匹配,并提供了完整的代码实现。

find_end(vs2010)

  • 引言
这是我学习总结<algorithm>的第十六篇。我是因为一个排序的实验结果,直奔<algorithm>C++库的,现在又仔细想想,我写那个排序算法,在实际当中会用自己的代码么?不会,只是能帮助自己了解的更彻底一点。
  • 作用
find_end的作用是在一段数据集合里找到可以匹配的指定一段数据集合的首地址,不过这个是从后往前找的。
  • 原型
template<class ForwardIterator1, class ForwardIterator2>
  ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,
                             ForwardIterator2 first2, ForwardIterator2 last2)
{
  if (first2==last2) return last1;  // specified in C++11

  ForwardIterator1 ret = last1;

  while (first1!=last1)
  {
    ForwardIterator1 it1 = first1;
    ForwardIterator2 it2 = first2;
    while (*it1==*it2) {    // or: while (pred(*it1,*it2)) for version (2)
        ++it1; ++it2;
        if (it2==last2) { ret=first1; break; }
        if (it1==last1) return ret;
    }
    ++first1;
  }
  return ret;
}
  • 实验
数据集合如下

匹配{1,2,3} ,返回的是第二个1的地址,
匹配{4,5,1},返回的是第一个4的地址。
  • 代码
test.cpp
#include <iostream>     // std::cout
#include <algorithm>    // std::find_end
#include <vector>       // std::vector

bool myfunction (int i, int j) 
{
	return (i==j);
}

int main () {
	int myints[] = {1,2,3,4,5,1,2,3,4,5};
	std::vector<int> haystack (myints,myints+10);

	int needle1[] = {1,2,3};

	// using default comparison:
	std::vector<int>::iterator it;
	it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3);

	if (it!=haystack.end())
		std::cout << "needle1 last found at position " << (it-haystack.begin()) << '\n';

	int needle2[] = {4,5,1};

	// using predicate comparison:
	it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction);

	if (it!=haystack.end())
		std::cout << "needle2 last found at position " << (it-haystack.begin()) << '\n';
	system("pause");
	return 0;
}


<think>嗯,用户这次想了解C++中几个常用头文件的作用,包括<iostream>、<vector>、<string>、<sstream>、<algorithm>和<unordered_map>。从引用内容看,用户可能正在学习C++标准库,特别是字符串处理和容器相关的部分。 用户引用的资料里提到了sstream的细节,说明ta对字符串流操作感兴趣。另外引用[3]的字符串处理示例也暗示用户可能需要实际应用这些头文件。考虑到用户之前没有提到具体项目,但连续询问库文件,应该是系统性地补充C++基础知识。 这些头文件确实是C++开发的核心组件。iostream是输入输出的基础,vector和unordered_map属于容器类,string和sstream处理字符串,algorithm提供通用算法。需要特别注意解释清楚: - iostream与sstream的区别(控制台IO vs 内存字符串IO) - vector和unordered_map的典型使用场景(顺序访问 vs 键值查找) - algorithm如何配合容器使用(比如sort需要传迭代器) 用户可能容易混淆sstream和string的边界,要强调string存储数据,sstream转化/解析数据。algorithm的非成员函数设计也是个关键点,最好用sort(v.begin(),v.end())这种典型用法说明。 之前引用[3]的字符串处理题涉及合并、排序、转换,正好可以用到<string>、<algorithm>和<sstream>。不过用户当前问题偏理论,暂时不需要展开代码示例,但可以在相关问题里准备实际应用场景的题目。 要避免把C++11的unordered_map和旧的map混淆解释。虽然用户没问区别,但在作用部分可以暗示“哈希实现”这个特性。另外iostream的cin/cout和scanf/printf的性能差异这类进阶内容当前可以不提。 </think>以下是C++中常用头文件的详细作用说明: --- ### **`<iostream>`** 提供**标准输入/输出流**功能: - `std::cin`:标准输入(如键盘输入) - `std::cout`:标准输出(控制台打印) - `std::cerr`:标准错误输出 - `std::endl`:换行并刷新缓冲区 **用途**:控制台交互、调试信息输出[^1]。 --- ### **`<vector>`** 实现**动态数组容器**: - 自动管理内存,支持动态扩容 - 随机访问元素:$O(1)$ 时间复杂度 - 尾部插入/删除:$O(1)$,中间操作:$O(n)$ **核心操作**: ```cpp std::vector<int> v = {1,2,3}; v.push_back(4); // 尾部插入 v[0]; // 访问元素 ``` **用途**:存储动态数据集(如不定长列表)[^2]。 --- ### **`<string>`** 提供**字符串类 `std::string`**: - 封装字符序列,自动管理内存 - 支持拼接、子串查找、替换等操作 **示例**: ```cpp std::string s = "Hello"; s += " World"; // 拼接 s.substr(0,5); // 子串 "Hello" ``` **用途**:文本处理、输入解析[^1][^3]。 --- ### **`<sstream>`** 实现**字符串流处理**: - `std::istringstream`:从字符串读取数据(类似 `cin`) - `std::ostringstream`:向字符串写入数据(类似 `cout`) - `std::stringstream`:读写双向操作 **示例**:字符串转整数 ```cpp std::string input = "42"; std::istringstream iss(input); int num; iss >> num; // num = 42 ``` **用途**:数据类型转换、字符串解析[^1][^3]。 --- ### **`<algorithm>`** 提供**通用算法模板**: - `std::sort()`:排序(平均 $O(n \log n)$) - `std::find()`:查找元素 - `std::reverse()`:反转序列 **示例**:排序向量 ```cpp std::vector<int> v = {3,1,2}; std::sort(v.begin(), v.end()); // v = {1,2,3} ``` **用途**:数据排序、搜索、变换等[^2]。 --- ### **`<unordered_map>`** 实现**哈希表(键值对容器)**: - 基于哈希函数存储键值对 - 插入/查找/删除:平均 $O(1)$,最坏 $O(n)$ - 键唯一且无序 **示例**:单词计数 ```cpp std::unordered_map<std::string, int> word_count; word_count["apple"] = 5; // 插入 int count = word_count["apple"]; // 查找 ``` **用途**:快速键值查询、去重计数[^2]。 --- ### **总结对比** | 头文件 | 核心功能 | 典型应用场景 | |----------------|----------------------------|--------------------------| | `<iostream>` | 控制台输入/输出 | 用户交互、日志输出 | | `<vector>` | 动态数组 | 动态数据集合存储 | | `<string>` | 字符串操作 | 文本处理、解析 | | `<sstream>` | 字符串流转换 | 数据类型转换、格式化 | | `<algorithm>` | 通用算法 | 排序、查找、遍历操作 | | `<unordered_map>` | 哈希表 | 键值快速检索、计数 | --- ### 相关问题 1. `std::vector` 和普通数组相比有哪些优势? 2. 如何用 `<algorithm>` 实现自定义排序规则? 3. `std::unordered_map` 和 `std::map` 的主要区别是什么? 4. 使用 `<sstream>` 时如何处理输入格式错误? 5. 哪些头文件是C++ STL(标准模板库)的核心组件? > 以上内容参考C++标准库文档及常见实践[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值