cpp
复制代码
/*******************************************************************************************
文件名 : _Algorithm.h
功能 : 通用算法,算法库
作者 : 李锋
手机 : 13828778863
Email : ruizhilf@139.com
创建时间 : 2024年07月02日
最后一次修改时间 : 2024年10月09日
注意 :所有base里的头文件都不要包含这个文件
注释 :每个算法函数都应该有一个用法例子
*********************************************************************************************/
#pragma once
#include "_p.h"
_LF_BEGIN_
/// <summary>
/// 用以描述配对
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间: 2024-08-15 最后一修改时间:2024-08-15
template<class Iterator>
class PairOf : _Object
{
public:
inline PairOf() = default;
/// <summary>
/// 指向左边配对数据的指针
/// </summary>
Iterator itLeft;
/// <summary>
/// 左路配对数据的长度
/// </summary>
size_t LeftLength = 0;
/// <summary>
/// 指向右边配对数据的指针
/// </summary>
Iterator itRight;
/// <summary>
/// 右边配对数据的长度
/// </summary>
size_t RigthLength = 0;
/// <summary>
/// 用于保存查找的左边配对的位置指针
/// </summary>
Iterator itLeftPosition;
/// <summary>
/// 用于保存查找的右边配对的位置指针
/// </summary>
Iterator itRigthPosition;
/// <summary>
/// 配对包含的数据的开始指针,此数据包含配对本身
/// </summary>
/// <returns></returns>
const Iterator begin()const { return itLeftPosition; }
/// <summary>
/// 配对包含的数据的结束位置的后一位指针,此数据包含配对本身
/// </summary>
/// <returns></returns>
const Iterator end()const { return itRigthPosition + RigthLength; }
/// <summary>
/// 返回配对包含的数据数据,包含配对本身
/// </summary>
/// <returns></returns>
auto PairData() {
using T = std::remove_reference_t<decltype(*itLeft)>;
int nLength = end() - begin();
lassert(itLeftPosition != null && itRigthPosition != null && nLength >= 0,"auto PairData()");
_Array<T> aResult(end() - begin() + 1);
Iterator it = itLeftPosition;
for (size_t n = 0; n < nLength; ++n) { *(aResult.GetDataConst() + n) = *(it + n); }
aResult.ResetLength(nLength);
aResult.ZeroBufferAll();
return aResult;
}
/// <summary>
/// 返回配对包含的数据数据,不包含配对本身
/// </summary>
/// <returns></returns>
inline auto PairOnlyData() {
using T = std::remove_reference_t<decltype(*itLeft)>;
int nLength = end() - begin() - LeftLength - RigthLength;
lassert(itLeftPosition != null && itRigthPosition != null && nLength >= 0,"PairOnlyData()");
_Array<T> aResult(end() - begin() + 1);
Iterator it = itLeftPosition + LeftLength;
for (size_t n = 0; n < nLength; ++n) { *(aResult.GetDataConst() + n) = *(it + n); }
aResult.ResetLength(nLength);
aResult.ZeroBufferAll();
return aResult;
}
};
/// <summary>
/// 不喜欢用 namespace::, 喜欢用 class., 因此用静态类。
/// lf::sort_selection 改用 alg.sort_selection
/// </summary>
/// 创建时间: 2024-07-25 最后一修改时间:2024-07-25
static class _Algorithm : public _Math
{
public:
/*****************************************************************************
排序
****************************************************************************/
//排序
//参考:https://blog.csdn.net/qq_45615577/article/details/115257685
//排序的概念
/*
排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次 序保持不变,即在原序列中,r[i] = r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排 序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。
------------------------------------------------
版权声明:本文为博主原创文章,遵循 CC 4.0 BY - SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https ://blog.csdn.net/qq_45615577/article/details/115257685
*/
/// <summary>
/// 选择排序---直接选择排序
/// 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,
/// 直到全部待排序的 数据元素排完 。
/// 找出序列中的最小关键字,然后将这个元素与序列首端元素交换位置。例如,序列前i个
/// 元素已经有序,从第i + 1到第n个元素中选择关键字最小的元素,假设第j个元素为最小
/// 元素,则交换第j个元素与第i + 1个元素的位置。依次执行此操作,直到第n - 1个元素
/// 也被确定。
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="pData">开始位置</param>
/// <param name="nCount">元素个数</param>
/// <param name="so">排序顺序,默认从小到大</param>
/// 创建时间: 2024-07-01 最后一修改时间:2024-07-01
/// 参考网址:https://blog.csdn.net/qq_45615577/article/details/115257685
template<class T>
void Sort_Selection(T* pData, const size_t& nCount, const bool& bMinMax = true)
{
/*
7 4 5 9 8 2 1
1 4 5 9 8 2 7
2 5 9 8 4 7
4 9 8 5 7
5 8 9 7
7 9 8
8 9
在 [0 , n-1] 中找出最小的放在第一位
在 [1 , n-1] 中找出最小的放在第二位
...
*/
if (pData == null || nCount == 0) return;
int nSortedCount = 0; //已排序好的个数
if (bMinMax) {
while (nSortedCount < nCount) {
int minIndex = nSortedCount;
//在[nStart, nCount-1] 中找出最小值
for (int n = nSortedCount + 1; n < nCount; ++n) {
if (*(pData + n) < *(pData + minIndex)) {
minIndex = n;
}
}
if (minIndex != nSortedCount) {
T tmp = *(pData + minIndex);
*(pData + minIndex) = *(pData + nSortedCount);
*(pData + nSortedCount) = tmp;
}
++nSortedCount;
}
}
else {
while (nSortedCount < nCount) {
int maxIndex = nSortedCount;
//在[nStart, nCount-1] 中找出最大值
for (int n = nSortedCount + 1; n < nCount; ++n) {
if (*(pData + n) > *(pData + maxIndex)) {
maxIndex = n;
}
}
if (maxIndex != nSortedCount) {
T tmp = *(pData + maxIndex);
*(pData + maxIndex) = *(pData + nSortedCount);
*(pData + nSortedCount) = tmp;
}
++nSortedCount;
}
}
}
/// <summary>
/// 返回最小值的位置
/// lf::_DList<int> d1 = { 1,3,5,8,2,0 };
/// lf::_DList<int> d2 = { 1 };
/// lf::_DList<int> d3 = { };
/// vector<int> v = { 1,3,5,8,2,0 };
///
/// _pin(*lf::Min(d1.begin(), d1.end())); //输出: 0
/// _pin(*lf::Min(d2.begin(), d2.end())); //输出: 1
/// _pin(*lf::Min(d3.begin(), d3.end())); //报错,最少一个元素
///
/// _pin(*lf::Min(v.begin(), v.end())); //输出: 0
///
/// _string s = _t("sdwsffa");
/// _pin(*lf::Min(s.begin(), s.end())); //输出: a
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <returns></returns>
/// 创建时间: 2024-07-02 最后一修改时间:2024-07-02
template<typename IteratorClass>
IteratorClass Min(IteratorClass itBegin, IteratorClass itEnd) {
assert(itBegin != itEnd);
IteratorClass result = itBegin;
itBegin++;
while (itBegin != itEnd) {
if (*result > *itBegin)
result = itBegin;
++itBegin;
}
return result;
}
/// <summary>
/// bool f(t1, t2){ }
/// 如果函数返回true,则认为 t1 < t2
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="fun"></param>
/// <returns></returns>
/// 创建时间: 2024-10-09 最后一修改时间:2024-10-09
template<typename IteratorClass, typename ComparingFunctions>
IteratorClass Min(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
assert(itBegin != itEnd);
IteratorClass result = itBegin;
itBegin++;
while (itBegin != itEnd) {
if( f(*itBegin, *result) ) //if *itbegin < *result
result = itBegin;
++itBegin;
}
return result;
}
/// <summary>
/// 按两种规则查找最小值:
/// 先按规则 f 比较,如果f没有比较成功(实际上两个对象按f
/// 规则比较是等于),则按对象本身自带的运算符 < 来比较。
/// 例子:
///
/// vector<string> v = { "abc6","abc1","abc3","abc2" };
///
/// auto s1 = alg.Min(v.begin(), v.end(), [](const string& s1, const string& s2)->bool {
/// return s1.size() < s2.size();
/// });
///
///
/// _pn(*s1);
/// auto s2 = alg.min_two_rules(v.begin(), v.end(), [](const string& s1, const string& s2)->bool {
/// return s1.size() < s2.size();
/// });
///
/// _pn(*s2);
///
/// 输出:
/// s1 = abc6
/// s2 = "abc1"
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-11 最后一修改时间:2024-10-11
template<typename IteratorClass, typename ComparingFunctions>
IteratorClass min_two_rules(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
assert(itBegin != itEnd);
IteratorClass result = itBegin;
itBegin++;
while (itBegin != itEnd) {
if (f(*itBegin, *result)) // 小于 if *itbegin < *result
result = itBegin;
else if (f(*result, *itBegin)) { //大小
//什么都不做
}else { //即不是大于,又不是小于,再按对象运算符规则
if(*itBegin < *result)
result = itBegin;
}
++itBegin;
}
return result;
}
/// <summary>
/// 创建时间: 2024-07-02 最后一修改时间:2024-07-02
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
template<typename IteratorClass ,typename ComparingFunctions>
IteratorClass Max(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
assert(itBegin != itEnd);
IteratorClass result = itBegin;
//itBegin++;
while (itBegin != itEnd) {
if ( !f(*itBegin, *result)) //if *itbegin < *result
result = itBegin;
++itBegin;
}
return result;
}
/// <summary>
///
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <returns></returns>
/// 创建时间: 2024-07-02 最后一修改时间:2024-07-02
template<typename IteratorClass>
IteratorClass Max(IteratorClass itBegin, IteratorClass itEnd) {
assert(itBegin != itEnd);
IteratorClass result = itBegin;
while (itBegin != itEnd) {
if (*result < *itBegin)
result = itBegin;
++itBegin;
}
return result;
}
/// <summary>
///
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="it1"></param>
/// <param name="it2"></param>
/// 创建时间: 2024-07-02 最后一修改时间:2024-10-09
template<typename IteratorClass>
void Swap(IteratorClass it1, IteratorClass it2) {
//std::cout << "===================================\n";
//_pin(*it1);
//_pin(*it2);
/*
auto tmp = *it1; //如果*it2是 int& 则,tmp 的类型是int, 并不是int&。
*it1 = *it2;
*it2 = tmp;
*/
_Math::swap(*it1, *it2);
//_pin(*it1);
//_pin(*it2);
//std::cout << "===================================\n";
}
/// <summary>
/// 输出itBegin到itEnd之间(不含itEnd)的所有元素,如果分隔符sSeparator为空,
/// 则每行输出一个元素,否则每个元素用分隔符分开。
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin">迭代器开始位置</param>
/// <param name="itEnd">迭代器结束位置</param>
/// <param name="sSeparator">分隔符</param>
/// 创建时间: 2024-08-01 最后一修改时间:2024-08-01
template<typename IteratorClass>
void Print(IteratorClass itBegin, IteratorClass itEnd, const std::string& sSeparator = "") {
//输出beg到end之间(不含end)的所有元素
if (itBegin == itEnd) return;
if (sSeparator == "") {
while (itBegin != itEnd)
std::cout << *itBegin++ << std::endl; //输出当前元素并将指针向前移动一个位置
std::cout << std::endl;
}
else {
while (itBegin != itEnd - 1)
std::cout << *itBegin++ << sSeparator; //输出当前元素并将指针向前移动一个位置
std::cout << *itBegin << std::endl;
}
}
/// <summary>
/// 输出集合的所有元素,如果分隔符sSeparator为空,
/// 则每行输出一个元素,否则每个元素用分隔符分开。
/// </summary>
/// <typeparam name="CollectionClass"></typeparam>
/// <param name="col">集合</param>
/// <param name="sSeparator">分隔符</param>
/// 创建时间: 2024-08-01 最后一修改时间:2024-08-01
template<typename CollectionClass>
void Print(const CollectionClass& col, const std::string& sSeparator = "") {
print(col.begin(), col.end(), sSeparator);
}
/// <summary>
/// lf::_DList<int> d4 = {1,2,3,6,5,4};
/// lf::sort_selection(d4.begin(), d4.end(), _SortOrder::s_Minmax);
/// _pcn(d4); //输出:d4={1,2,3,4,5,6}
/// lf::sort_selection(d4.begin(), d4.end(), _SortOrder::s_Maxmin);
/// _pcn(d4); //输出:d4={6,5,4,3,2,1}
///
/// _string s2 = _t("_DListNodeIterator,abcd,efg");
/// _pcn(s2); //s2=_DListNodeIterator,abcd,efg
/// lf::sort_selection(s2.begin(), s2.end(), _SortOrder::s_Minmax);
/// _pcn(s2); //s2=,,DILN_aabcddeeefgioorrsttt
/// lf::sort_selection(s2.begin(), s2.end(), _SortOrder::s_Maxmin);
/// _pcn(s2); //s2=tttsrrooigfeeeddcbaa_NLID,,
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="so"></param>
/// 创建时间: 2024-07-01 最后一修改时间:2024-10-09(已测试)
template<typename IteratorClass>
void Sort_Selection(IteratorClass itBegin, IteratorClass itEnd, const bool& bMinMax = true)
{
/*
7 4 5 9 8 2 1
1 4 5 9 8 2 7
2 5 9 8 4 7
4 9 8 5 7
5 8 9 7
7 9 8
8 9
7 2 2 2 2 2 2
2 7 2 2 2 2 2
2 7 2 2 2 2
2 7 2 2 2
2 7 2 2
2 7 2
2 7
在 [0 , n-1] 中找出最小的放在第一位
在 [1 , n-1] 中找出最小的放在第二位
...
*/
if (bMinMax) {
while (itBegin != itEnd) {
//在[itBegin + 1, itEnd] 中找出最小值,与itBegin交换
Swap(itBegin, Min(itBegin, itEnd));
itBegin++;
}
}
else {
while (itBegin != itEnd) {
//在[itBegin + 1, itEnd] 中找出最小值,与itBegin交换
Swap(itBegin, Max(itBegin, itEnd));
itBegin++;
}
}
}
template<typename IteratorClass>
void sort(IteratorClass itBegin, IteratorClass itEnd) {
Sort_Selection(itBegin, itEnd);
}
/// <summary>
/// std::sort 是从小到大排列的
/// 例子代码:
/// list<int> lst1 = { 0,3,2,3,9,9,7,6,5,4,3,1 };
/// _list<int> lst2 = { 0,3,2,3,9,9,7,6,5,4,3,1 }; //_DList
/// alg.sort(lst1.begin(), lst1.end(), [](const int& i1, const int& i2)->bool {
/// return i1 < i2;
/// });
/// alg.sort(lst2.begin(), lst2.end(), [](const int& i1, const int& i2)->bool {
/// return i1 < i2;
/// });
/// _pn(lst1);
/// _pn(lst2);
///
/// 输出:
/// lst1 = {0,1,2,3,3,3,4,5,6,7,9,9}
/// lst2 = {0,1,2,3,3,3,4,5,6,7,9,9}
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// 创建时间: 2024-10-09 最后一修改时间:2024-10-09(已测试)
template<typename IteratorClass, typename ComparingFunctions>
void sort(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
while (itBegin != itEnd) {
Swap(itBegin, Min(itBegin, itEnd,f)); //与std::sort相同,从小到大
itBegin++;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// 创建时间: 2024-10-12 最后一修改时间:2024-10-12(已测试)
template<typename IteratorClass, typename ComparingFunctions>
void sort_two_rules(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
while (itBegin != itEnd) {
Swap(itBegin, min_two_rules(itBegin, itEnd, f)); //与std::sort相同,从小到大
itBegin++;
}
}
/// <summary>
/// 稳定排序:
/// 在排序时不改变其序列
/// 待排序的记录序列中可能存在两个或两个以上关键字相等的记录。
/// 排序前的序列中Ri领先于Rj(即i<j).若在排序后的序列中Ri仍然领先于Rj,
/// 则称所用的方法是稳定的。比如int数组 [1, 1, 1, 6, 4] 中 a[0], a[1], a[2]的
/// 值相等,在排序时不改变其序列,则称所用的方法是稳定的。
///
/// stable_sort 是 C++ 标准库中的一个算法,用于对指定范围内的元素进行排序。
/// 与 std::sort 不同,stable_sort 保证了相等元素的相对顺序不变,即稳定排序。
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// 创建时间: 2024-10-11 最后一修改时间:2024-10-11(已测试)
template<typename IteratorClass, typename ComparingFunctions>
void stable_sort(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
IteratorClass itSwap = itBegin;
while (itBegin != itEnd) {
auto itMin = Min(itBegin, itEnd, f);
//判断下一个元素是否与itBegin相等,如果相等,则itBegin指向下一个元素
auto itSwap = itBegin + 1;
while (itBegin != itEnd && itBegin != itMin) {
//itBegin和itswap相等
if ( f(*itBegin, *itSwap) == false && f(*itSwap, *itBegin) == false)
{
itSwap++;
}else {
//abc1,abc2,abc3 c a (先保存a元素,然后 [abc1,abc3,abc3,c] 后移一位
//a,abc1 abc2,abc3,c
auto tValue = *itMin; //保存数据
m.MoveBackIter(itBegin, itMin, 1);
*itBegin = tValue;
//itBegin = itSwap; 错误,不能用这句,还是在itBegin之前插入
//std::cout << "*itBegin=" << (*itBegin) << "\n";
//std::cout << "*itBegin=" << (*(itBegin+1)) << "\n";
break;
}
}
itBegin++;
}
}
/*****************************************************************************
查找
顺序查找
二分查找
插值查找、
斐波那契查找
分块查找
哈希查找
树表查找
****************************************************************************/
template<typename IteratorType>
struct findResult
{
/// <summary>
/// 如果没找到 Index == -1
/// </summary>
size_t Index;
IteratorType Iter;
public:
inline findResult() { Index = _Math::npos; }
inline findResult(const findResult& r) {
Index = r.Index;
Iter = r.Iter;
}
};
/// <summary>
/// 顺序查找
///
/// 注意:
/// 如果是向后查找,则返回的索引是以itFirst开始算来,第一个为 0,即itFirst为0。
/// 如果是向前揸找,则返回的索引是以itLast开始算起,第一个,即itLast为0。
///
/// </summary>
/// <typeparam name="IteratorType"></typeparam>
/// <typeparam name="DataType"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="tValue"></param>
/// <param name="bBackward"></param>
/// <returns></returns>
/// 创建时间: 2024-07-03 最后一修改时间:2024-07-03
template<typename IteratorType, typename DataType>
findResult<IteratorType> Find_Sequential(IteratorType itFirst, IteratorType itLast,
const DataType& tFindValue, const bool& bBackward = true)
{
findResult<IteratorType> fr;
fr.Index = -1;
int n = 0;
if (bBackward) { //向后
while (true)
{
if (*itFirst == tFindValue) {
fr.Index = n;
fr.Iter = itFirst;
break;
}
++n;
++itFirst;
if (itFirst == itLast) break;
}
}
else {
while (true)
{
if (*itLast == tFindValue) {
fr.Index = n;
fr.Iter = itLast;
break;
}
++n;
--itLast;
if (itFirst == itLast) break;
}
}
return fr;
}
/// <summary>
/// 集合类必须带有 begin() 和 end() 函数
/// 例子:
/// std::vector<int> v = { 1,2,3,23,435,4646,34 };
/// lf::_DList<int> d = { 1,2,3,23,435,4646,34 };
/// if (lf::IsExists(d, 23))
/// {
/// cout << "存在23.\n";
/// }
/// if (lf::IsExists(v, 55))
/// {
/// cout << "存在55.\n";
/// }
/// </summary>
/// <typeparam name="value_type"></typeparam>
/// <typeparam name="CollectionClass"></typeparam>
/// <param name="col"></param>
/// <param name="value"></param>
/// <returns></returns>
/// 创建时间: 2024-07-03 最后一修改时间:2024-07-03
template<typename CollectionClass, typename value_type>
bool IsExists(const CollectionClass& col, const value_type& value)
{
auto itbegin = col.begin();
auto itend = col.end();
while (itbegin != itend)
{
if (*itbegin == value)
return true;
++itbegin;
}
return false;
}
/// <summary>
/// 二分法查找有序表的通用算法(可查链表,数组,字符串...等等)
/// 注意事项:
/// (1)你设计的迭代器模板中必须有using value_type = T,且有加减运算功能,
/// 其本上能与C++标准库std中一样。
/// (2)集合必须是有序的。
/// 例子:
/// vector<int> v;
/// find_binary(b.begin(),v.end(),3); // Inde返回 (-1, *Iterator == ?)
///
/// vector<int> v = {3};
/// find_binary(b.begin(),v.end(),3); // 返回 (Index == 0, *Iterator == 3)
///
/// const char* sz = "abcdefgb";
/// auto f3 = lf::find_binary(sz, sz + 8, 'c'); //返回 (Index == 2, *Iterator == c)
/// </summary>
/// <typeparam name="IteratorType">迭代器类型</typeparam>
/// <typeparam name="value_type">值类型</typeparam>
/// <param name="itBegin">开始位置</param>
/// <param name="itEnd">结束位置</param>
/// <param name="vtFindValue">查找值</param>
/// <returns>返回索引与指向vtFindValue的迭代器</returns>
/// 创建时间: 2024-07-03 最后一修改时间:2024-07-04 (初步测试)
template<typename IteratorType,typename value_type>
findResult<IteratorType> find_binary(const IteratorType& itBegin,
const IteratorType& itEnd, const value_type& vtFindValue)
{
findResult<IteratorType> fr;
auto beg = itBegin;
auto end = itEnd;
int nCount = end - beg;
if (nCount == 0) return fr;
if (*(itEnd-1) > *itBegin) {//从小到大排列
auto mid = beg + nCount / 2;
while (mid != itEnd){
if(*mid == vtFindValue){
fr.Iter = mid;
fr.Index = mid - itBegin;
return fr;
}
if (vtFindValue < *mid)
end = mid;
else
beg = mid + 1; //在mid之后查找
mid = beg + (end - beg) / 2; //新的中间点
}
}else{ //从大到小排列
auto mid = beg + nCount / 2;
while (mid != itEnd) {
if (*mid == vtFindValue) {
fr.Iter = mid;
fr.Index = mid - itBegin;
return fr;
}
if (vtFindValue > *mid)
end = mid;
else
beg = mid + 1; //在mid之后查找
mid = beg + (end - beg) / 2; //新的中间点
}
}
return fr;
}
/// <summary>
/// 查找元素是否存在,或者计算元素个数。
/// 例:
/// _DList<int> d1 = { 1,3,4,5,3 };
/// size_t n;
/// 执行: alg.IsExistsElement(d1, 3, &n, true)) 则 n = 2, 并且函数返回true
/// alg.IsExistsElement(d1, 3), 函数返回true
/// </summary>
/// <typeparam name="CollectionClass">集合类型</typeparam>
/// <typeparam name="Element_Type">集合元素类型</typeparam>
/// <param name="col">集合</param>
/// <param name="Value">元素值</param>
/// <param name="pCount">保存元素个数的变量指针</param>
/// <param name="IsStatisticsCount">是否计算出现个数</param>
/// <returns></returns>
/// 创建时间: 2024-07-30 最后一修改时间:2024-07-30 (初步测试)
template<typename CollectionClass,typename Element_Type>
bool IsExistsElement(const CollectionClass& col, const Element_Type &Value,
size_t* pCount = null, const bool &IsStatisticsCount = false)
{
size_t nSize = col.size();
auto itBegin = col.begin();
if (IsStatisticsCount){
assert(pCount != null);
*pCount = 0;
for (size_t n = 0; n < nSize; ++n) {
if (*(itBegin + n) == Value){
*pCount = *pCount + 1;
}
}
return *pCount != 0;
}else{
for (size_t n = 0; n < nSize; ++n){
if (*(itBegin + n) == Value)
return true;
}
return false;
}
}
/// <summary>
/// 检查母集合中是否存在子集.
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <param name="itParentBegin">母集开始位置</param>
/// <param name="itParentEnd">>母集结束位置</param>
/// <param name="itSubBegin">子集开始位置</param>
/// <param name="itSubEnd">子集结束位置</param>
/// <returns></returns>
/// 创建时间: 2024-07-24 最后一修改时间:2024-07-24 (初步测试)
template<typename IteratorClass>
bool IsContain(const IteratorClass& itParentBegin, const IteratorClass& itParentEnd,
const IteratorClass& itSubBegin,const IteratorClass& itSubEnd) {
//母串集合元集
size_t nParentSize = itParentEnd - itParentBegin;
//字串集合元素
size_t nSubSize = itSubEnd - itSubBegin;
if (nSubSize == 0 || nParentSize == 0 || nSubSize > nParentSize) return false;
for (size_t i = 0; i < nParentSize - nSubSize + 1; ++i) {
bool isSub = true;
for (size_t j = 0; j < nSubSize; ++j){
if ( *(itParentBegin + i + j) != *(itSubBegin + j) ) {
isSub = false;
break;
}
}
if (isSub) return true;
}
return false;
}
/*
/// <summary>
/// 检查母集合中是否存在子集.
/// </summary>
/// <param name="vecParent">母集</param>
/// <param name="vecSub">子集</param>
/// <returns></returns>
/// 创建时间: 2024-07-24 最后一修改时间:2024-07-24 (初步测试)
inline bool IsContain(const std::vector<int>& vecParent, const std::vector<int>& vecSub)
{
if (vecParent.size() == 0 || vecSub.size() == 0 || vecSub.size() > vecParent.size())
return false;
for (size_t i = 0; i < vecParent.size() - vecSub.size() + 1; ++i) {
bool bFind = true;
for (size_t j = 0; j < vecSub.size(); ++j) {
if (vecParent[i + j] != vecSub[j]) {
bFind = false;
break;
}
}
if (bFind) return true;
}
return false;
}
*/
/// <summary>
/// 检查母集合colParent中是否存在子集colSub。
/// </summary>
/// <typeparam name="CollectionClass"></typeparam>
/// <param name="colParent"></param>
/// <param name="colSub"></param>
/// <returns></returns>
/// 创建时间: 2024-07-25 最后一修改时间:2024-07-25 (初步测试)
template<typename CollectionClass>
bool IsContain(const CollectionClass& colParent, const CollectionClass& colSub) {
//母串集合元集
size_t nParentSize = colParent.size();
auto itParentBegin = colParent.begin();
auto itSubBegin = colSub.begin();
//字串集合元素
size_t nSubSize = colSub.size();
if (nSubSize == 0 || nParentSize == 0 || nSubSize > nParentSize) return false;
for (size_t i = 0; i < nParentSize - nSubSize + 1; ++i) {
bool isSub = true;
for (size_t j = 0; j < nSubSize; ++j) {
if (*(itParentBegin + i + j) != *(itSubBegin + j)) {
isSub = false;
break;
}
}
if (isSub) return true;
}
return false;
}
/***************************************************************
FindFirstOf使用例子代码:
_string s1 = "(int)";
_string s2 = "int";
auto s = FindFirstOf(s1.begin(), s1.end(), s2.begin(), s2.end());
if (s != null)
_cout << s;
输出:
int)
***************************************************************/
/// <summary>
/// 查找一段数据第一次出现的位置。
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="itParentBegin">母数据指针开始位置</param>
/// <param name="itParentEnd">母数据开始结束位置,对于字符串,即:psz + strLength </param>
/// <param name="itSubBegin">子数据指针开始位置</param>
/// <param name="itSubEnd">子数据开始结束位置,对于字符串,即:psz + strLength </param>
/// <returns>如找到,返回这段数据第一次出现的指针位置,否则返回nuLL。</returns>
/// 创建时间: 2024-08-15 最后一修改时间:2024-08-15 (已测试)
template<typename Iterator>
inline Iterator findFirstOf(const Iterator& itParentBegin, const Iterator& itParentEnd,
const Iterator& itSubBegin, const Iterator& itSubEnd) {
const int nParentLength = itParentEnd - itParentBegin;
const int nSubLength = itSubEnd - itSubBegin;
if (nSubLength <= 0 || nSubLength > nParentLength) return Iterator();
Iterator Result = itParentBegin;
//别忘了加上1
const Iterator end = itParentBegin + nParentLength - nSubLength + 1;
while (Result != end) {
bool bFind = true;
//判断这一段数据是否相等
for (int n = 0; n < nSubLength; ++n) {
if (*(Result + n) != *(itSubBegin + n)) {
bFind = false;
break;
}
}
if (bFind) return Result;
++Result;
}
return Iterator();
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="beginPtr"></param>
/// <param name="endPtr"></param>
/// <param name="p"></param>
/// <returns></returns>
/// 创建时间: 2024-08-15 最后一修改时间:2024-08-15 (已测试)
template<class IterClass>
inline bool findPairOfFirst(const IterClass& itBegin, const IterClass& itEnd,
PairOf<IterClass>& p)
{
//查找左边第一次出现的位置
p.itLeftPosition = findFirstOf(itBegin, itEnd, p.itLeft, p.itLeft + p.LeftLength);
//查找右边第一次出现我
if (p.itLeftPosition != null)
{
p.itRigthPosition = FindFirstOf(p.itLeftPosition + p.LeftLength, itEnd, p.itRight,
p.itRight + p.RigthLength);
}
return p.itLeftPosition != null && p.itRigthPosition != null;
}
/// <summary>
/// 用二分法查找插入点,迭代器要支持 +,- >=、<=
/// 不支持 std::list
/// 支持 std::vector, lf::DList
///
/// 例子:
/// _list<int> lst1{0,2,4,5,6,7,8};
/// _list<int> lst2{ 8,7,6,5,4,3,2,1};
/// _list<int> a1;
/// _list<int> a2 = {1};
///
/// alg.find_binary_insert_pos(lst1.begin(), lst1.end(), 0,true)=1
/// alg.find_binary_insert_pos(lst1.begin(), lst1.end(), 3, true) = 2
/// alg.find_binary_insert_pos(lst1.begin(), lst1.end(), -9, true) = 0
/// alg.find_binary_insert_pos(lst2.begin(), lst2.end(), 1, false) = 7
/// alg.find_binary_insert_pos(lst2.begin(), lst2.end(), 3, false) = 5
/// alg.find_binary_insert_pos(lst2.begin(), lst2.end(), -1, false) = 8
/// alg.find_binary_insert_pos(lst2.begin(), lst2.end(), 9, false) = 0
/// alg.find_binary_insert_pos(a1.begin(), a1.end(), 9, false) = 0
/// alg.find_binary_insert_pos(a2.begin(), a2.end(), 9, true) = 1
///
/// </summary>
/// <typeparam name="IterClass"></typeparam>
/// <typeparam name="ElemType"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="etValue"></param>
/// <param name="bAscending">是否升序</param>
/// <returns></returns>
/// 创建时间: 2024-10-27 最后一修改时间:2024-10-27 (已测试) (花了一整天时间,七小时)
template<class IterClass, class ElemType>
inline size_t find_binary_insert_pos(const IterClass& itBegin, const IterClass& itEnd,
const ElemType& etValue, const bool& bAscending = true){
if (itEnd == itBegin) return 0;
lassert(itEnd > itBegin, "find_binary_insert_pos");
size_t nLength = itEnd - itBegin;
size_t mid = nLength / 2;
if (bAscending) { //升序
while (mid < nLength && mid >= 0) {
IterClass it = itBegin + mid;
if (*it < etValue) {
if (mid != nLength - 1) {
if (*(it + 1) >= etValue) {
return mid + 1;
}else { //在右边继续找
mid = mid + (nLength - mid) / 2;
}
}else {
return nLength;
}
}
else if (*it > etValue) {
if (mid != 0) {
if (*(it - 1) <= etValue) {
return mid;
}else { //在左边继续找
mid = mid - (mid + 1) / 2;
}
}else{
return 0;
}
}else {
return mid;
}
}
}else{ //降序
while (mid < nLength && mid >= 0) {
IterClass it = itBegin + mid;
if( *it > etValue ) {
if (mid != nLength - 1) {
//可能不支持 >=
if (*(it + 1) <= etValue) {
return mid + 1;
}else { //在右边继续找
mid = mid + (nLength - mid) / 2;
}
}else{
return nLength;
}
}else if (*it < etValue) {
if (mid != 0) {
if (*(it - 1) >= etValue) {
return mid;
}else { //在左边继续找
mid = mid - (mid + 1) / 2;
}
}else {
return 0;
}
}else {
return mid;
}
}
}
throw("无法找到插入位置,算法错误!");
}
/// <summary>
/// 用二分法查找有序容器的插入点,如果容器中存在同样的元素,
/// 则返回npos.
/// 迭代器要支持 +,- >=、<=。
/// </summary>
/// <typeparam name="IterClass"></typeparam>
/// <typeparam name="ElemType"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="etValue"></param>
/// <param name="bAscending"></param>
/// <returns></returns>
/// 创建时间: 2024-10-27 最后一修改时间:2024-10-27 (已测试) (花了一整天时间,七小时)
template<class IterClass, class ElemType>
inline size_t find_binary_insert_unique_pos(const IterClass& itBegin, const IterClass& itEnd,
const ElemType& etValue, bool bAscending = true) {
if (itEnd == itBegin) return 0;
lassert(itEnd > itBegin, "find_binary_insert_unique_pos");
size_t nLength = itEnd - itBegin;
size_t mid = nLength / 2;
if (bAscending) { //升序
while (mid < nLength && mid >= 0) {
IterClass it = itBegin + mid;
if (*it < etValue) {
if (mid != nLength - 1) {
if (*(it + 1) == etValue) {
return _Math::npos;
}else if (*(it + 1) > etValue) {
return mid + 1;
}
else { //在右边继续找
mid = mid + (nLength - mid) / 2;
}
}
else {
return nLength;
}
}
else if (*it > etValue) {
if (mid != 0) {
if (*(it + 1) == etValue) {
return _Math::npos;
}
else if(*(it - 1) < etValue) {
return mid;
}
else { //在左边继续找
mid = mid - (mid + 1) / 2;
}
}
else {
return 0;
}
}
else {
return _Math::npos;
}
}
}
else { //降序
while (mid < nLength && mid >= 0) {
IterClass it = itBegin + mid;
if (*it > etValue) {
if (mid != nLength - 1) {
if (*(it + 1) == etValue) {
return _Math::npos;
}else if (*(it + 1) < etValue) {
return mid + 1;
}
else { //在右边继续找
mid = mid + (nLength - mid) / 2;
}
}
else {
return nLength;
}
}
else if (*it < etValue) {
if (mid != 0) {
if (*(it + 1) == etValue) {
return _Math::npos;
}else if (*(it - 1) > etValue) {
return mid;
}
else { //在左边继续找
mid = mid - (mid + 1) / 2;
}
}
else {
return 0;
}
}
else {
return _Math::npos;
}
}
}
throw("无法找到插入位置,算法错误!");
}
/// <summary>
/// 获取配对中间的数据,例 (a): for(int i) = 0 ,如果是括号为配对,
/// 那么获取的数据是 "a" 和 "int i" 。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="beginPtr"></param>
/// <param name="endPtr"></param>
/// <param name="p"></param>
/// <returns></returns>
/// 创建时间: 2024-08-15 最后一修改时间:2024-08-15 (已测试)
template<class Iterator>
auto extractionPairData(const Iterator& itBegin, const Iterator& itEnd, PairOf<Iterator>& p)
{
using T = std::remove_reference_t<decltype(*itBegin)>;
_DList<_Array<T>> result;
auto f = FindPairOfFirst(itBegin, itEnd, p);
while (f)
{
result.Add(p.PairOnlyData());
f = FindPairOfFirst(p.itRigthPosition + p.RigthLength, itEnd, p);
}
return result;
}
template<class CollectionClass, class ValueType>
_DList<CollectionClass> extractionPairData(const CollectionClass& col,
const CollectionClass left, const CollectionClass& right) {
_DList<CollectionClass> result;
/*
auto f = FindPairOfFirst(itBegin, itEnd, p);
while (f)
{
result.Add(p.PairOnlyData());
f = FindPairOfFirst(p.itRigthPosition + p.RigthLength, itEnd, p);
}
*/
return result;
}
/// <summary>
/// 计数colParent包含有多少个colSub,跟IsContain算法一样,但是
/// IsContain找到立即返回。
/// </summary>
/// <typeparam name="CollectionClass">具有迭代性质的类</typeparam>
/// <param name="colParent">母集合</param>
/// <param name="colSub">子集合</param>
/// <returns></returns>
/// 创建时间: 2024-07-29 最后一修改时间:2024-07-29
template<typename CollectionClass>
int count(const CollectionClass &colParent, const CollectionClass &colSub) {
int nResult = 0;
//母串集合元集
size_t nParentSize = colParent.size();
auto itParentBegin = colParent.begin();
auto itSubBegin = colSub.begin();
//字串集合元素
size_t nSubSize = colSub.size();
if (nSubSize == 0 || nParentSize == 0 || nSubSize > nParentSize) return false;
for (size_t i = 0; i < nParentSize - nSubSize + 1; ++i) {
bool isSub = true;
for (size_t j = 0; j < nSubSize; ++j) {
if (*(itParentBegin + i + j) != *(itSubBegin + j)) {
isSub = false;
break;
}
}
if (isSub)
++nResult;
}
return nResult;
}
///
/// <summary>
/// 标准库定义了一个名为count_if的算法。类似find_if,此函数接受
/// 一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围内每个元素执行。
/// cout_if返回一个计数值,表示谓词有多少次为真。
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-15 最后一修改时间:2024-10-15
template<typename IteratorClass, typename ComparingFunctions>
size_t count_if(const IteratorClass& itBegin, const IteratorClass& itEnd,
const ComparingFunctions& f) {
size_t nResult = 0;
for (auto it = itBegin; it != itEnd; ++it) {
if (f(*it))
++nResult;
}
return nResult;
}
///
/// <summary>
/// 如果是数组:
/// int ia[] = { 1,2,3,4,5 };
/// accumulate(ia + 0, ia + 5, 0);
///
/// accumulate的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型
/// </summary>
/// <typeparam name="value_type"></typeparam>
/// <typeparam name="IterClass"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="InitialValue"></param>
/// <returns></returns>
/// 创建时间: 2024-10-07 最后一修改时间:2024-10-07
template<class IterClass, class value_type>
static value_type accumulate(
const IterClass& begin,
const IterClass& end,
const value_type& InitialValue) {
value_type sum = InitialValue;
size_t n = 0;
while (begin + n < end)
{
sum += *(begin + n);
++n;
}
return sum;
}
/// <summary>
///
/// </summary>
/// <typeparam name="IterClass"></typeparam>
/// <param name="begin1"></param>
/// <param name="end1"></param>
/// <param name="begin2"></param>
/// <returns></returns>
/// 创建时间: 2024-10-07 最后一修改时间:2024-10-07
template<class IterClass>
static bool equal(
const IterClass& begin1,
const IterClass& end1,
const IterClass& begin2) {
size_t n = 0;
while (begin1 + n < end1)
{
if (*(begin1 + n) != *(begin2 + n))
return false;
++n;
}
return true;
}
/// <summary>
///
/// </summary>
/// <typeparam name="IterClass"></typeparam>
/// <typeparam name="value_type"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="tFill"></param>
/// 创建时间: 2024-10-07 最后一修改时间:2024-10-07
template<class IterClass, class value_type>
static void fill(
const IterClass& begin,
const IterClass& end,
const value_type& tFill = value_type()) {
size_t n = 0;
while (begin + n < end)
{
*(begin + n) = tFill;
++n;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="IterClass"></typeparam>
/// <typeparam name="value_type"></typeparam>
/// <param name="begin"></param>
/// <param name="nCount"></param>
/// <param name="tFill"></param>
/// 创建时间: 2024-10-07 最后一修改时间:2024-10-07
template<class IterClass, class value_type>
static void fill_n(
const IterClass& begin,
const size_t& nCount,
const value_type& tFill = value_type()) {
size_t n = 0;
/*
for(size_t n = 0; n < nCount; ++n)
{
*(begin + n) = tFill;
}
*/
IterClass it = begin;
for (size_t n = 0; n < nCount; ++n)
{
*(it) = tFill;
it++;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="dest"></param>
/// <returns></returns>
/// 创建时间: 2024-10-07 最后一修改时间:2024-10-07
template<class T>
const T* copy(const T* begin, const T* end, T* dest) {
T* it1 = (T*)begin;
T* it2 = dest;
while (it1 < end) {
*it2++ = *it1++;
}
return it2;
}
/// <summary>
/// 例子:
/// int main() {
/// vector<int> vec = { 1,2,3,4 };
/// ostream_iterator<int> out_iter(cout, " ");
/// alg.copy(vec.begin(), vec.end(), out_iter);
/// cout << endl;
/// return 0;
/// }
///
/// 输出:
/// 1 2 3 4
///
/// </summary>
/// <typeparam name="InIter"></typeparam>
/// <typeparam name="OutIter"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="dest"></param>
/// <returns></returns>
/// 创建时间: 2024-10-18 最后一修改时间:2024-10-18
template<class InIter, class OutIter>
OutIter copy(InIter begin, InIter end, OutIter dest) {
/*
* std::源码:
_EXPORT_STD template <class _InIt, class _OutIt>
_CONSTEXPR20 _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest) { // copy [_First, _Last) to [_Dest, ...)
_STD _Adl_verify_range(_First, _Last);
const auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
const auto _UDest = _STD _Get_unwrapped_n(_Dest, _STD _Idl_distance<_InIt>(_UFirst, _ULast));
_STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst, _ULast, _UDest));
return _Dest;
}
*/
while (begin < end) {
*dest++ = *begin++;
}
return dest;
}
/// <summary>
/// 例子:
///
/// string s = "abcda-";
///
/// _list<int> ilst1 = { 3,5,0,130,0 };
/// list<int> ilst2 = { 3,5,0,130,0 };
///
/// //将所有值为0的元素改为42
/// alg.replace(ilst1.begin(), ilst1.end(), 0, 42);
/// alg.replace(ilst2.begin(), ilst2.end(), 0, 42);
///
/// char sz[] = "abcda";
///
/// alg.replace(s.begin(), s.end(), 'a', 'w');
/// alg.replace(&sz[0], sz + 5, 'a', 'w');
///
/// _pn(ilst1);
/// _pn(ilst2);
/// _pn(s);
/// _pn(sz);
///
/// 输出:
///
/// ilst1={3,5,42,130,42}
/// ilst2={3,5,42,130,42}
/// s="wbcdw-"
/// sz="wbcdw"
///
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="value_type"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="old_value"></param>
/// <param name="new_value"></param>
/// 创建时间: 2024-10-08 最后一修改时间:2024-10-08
template<class itClass,class value_type>
void replace(const itClass& begin, const itClass& end, const value_type& old_value,
const value_type& new_value) {
//itClass it = begin;
itClass it = begin;
//这里要 != ,不能 while (it < end) 因为在链表中,可能不会重载小于运算符
while (it != end) {
if (*it == old_value) {
*it = new_value;
}
it++;
}
}
/// <summary>
/// 注意:std::replace_copy第三个参数为 back_inserter
/// 例子:
/// list<int> ilst = { 0, 1,2,3 };
/// vector<int> ivec{ 3,3 };
///
/// std:
///
/// //使用back_inserter按需要增长目标序列
/// //replace_copy(ilst.cbegin(), ilst.cend(),
/// // back_inserter(ivec), 0, 42);
///
///
/// alg.replace_copy(ilst.cbegin(), ilst.cend(), ivec, 0, 42);
/// _pn(ilst);
/// _pn(ivec);
/// 输出:
/// ilst={0,1,2,3}
/// ivec = { 3,3,42,1,2,3 }
/// </summary>
/// <typeparam name="itClass"></typeparam>
/// <typeparam name="container_class"></typeparam>
/// <typeparam name="value_type"></typeparam>
/// <param name="begin"></param>
/// <param name="end"></param>
/// <param name="cc"></param>
/// <param name="old_value"></param>
/// <param name="new_value"></param>
/// <returns></returns>
/// 创建时间: 2024-10-08 最后一修改时间:2024-10-08
template<class itClass, class container_class, class value_type>
container_class& replace_copy(const itClass& begin, const itClass& end,
container_class& cc,
const value_type& old_value,
const value_type& new_value) {
//itClass it = begin;
itClass it = begin;
//这里要 != ,不能 while (it < end) 因为在链表中,可能不会重载小于运算符
while (it != end) {
if (*it == old_value) {
cc.push_back(new_value);
}else{
cc.push_back(*it);
}
it++;
}
return cc;
}
/// <summary>
/// 返回一个unique的拷贝,注意,如果已排序的集合速度会很快。
/// </summary>
/// <typeparam name="container_class"></typeparam>
/// <param name="cCopy"></param>
/// <param name="is_sorted"></param>
/// <returns></returns>
/// 创建时间: 2024-10-08 最后一修改时间:2024-10-08
template<class container_class>
container_class unique_copy(const container_class& cCopy, bool is_sorted = false) {
container_class cResult;
if (cCopy.size() == 0) return cResult;
auto it = cCopy.begin(), itend = cCopy.end();
if (is_sorted) {
cResult.push_back(*it);
it++;
while (it != itend) {
if (*it != *(cResult.end() - 1)) {
cResult.push_back(*it);
}
it++;
}
}else {
while (it != itend) {
if (!IsExists(cResult, *it)) {cResult.push_back(*it);}
it++;
}
}
return cResult;
}
///
/// <summary>
/// find_if 是一个在 C++ 标准库 <algorithm> 头文件中定义的函数模板,用于
/// 在一个范围内查找满足特定条件的第一个元素。它的原型如下
///
/// template <class InputIterator, class UnaryPredicate>
/// InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate p);
///
/// first:范围的起始迭代器。
/// last:范围的结束迭代器。
/// p:一个一元谓词函数,用于判断元素是否满足条件。
///
/// find_if 函数返回一个指向满足条件的第一个元素的迭代器,如果没有找到满足条件的元素,则返回 last
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-12 最后一修改时间:2024-10-12
template<typename IteratorClass, typename ComparingFunctions>
IteratorClass find_if(const IteratorClass& itBegin, const IteratorClass& itEnd, ComparingFunctions f) {
/*
_EXPORT_STD template <class _InIt, class _Pr>
_NODISCARD _CONSTEXPR20 _InIt find_if(_InIt _First, const _InIt _Last, _Pr _Pred) { // find first satisfying _Pred
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _STD _Get_unwrapped(_First);
const auto _ULast = _STD _Get_unwrapped(_Last);
for (; _UFirst != _ULast; ++_UFirst) {
if (_Pred(*_UFirst)) {
break;
}
}
_STD _Seek_wrapped(_First, _UFirst);
return _First;
}
*/
for (; itBegin != itEnd; ++itBegin) {
if (f(*itBegin)) {
return itBegin;
}
}
return itEnd;
}
/// <summary>
/// 从后面开始查找 [itBegin,itEnd) 第一个符合条件的元素,如找不到,返回itEnd;
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-12 最后一修改时间:2024-10-12 (已测试)
template<typename IteratorClass, typename ComparingFunctions>
IteratorClass rfind_if(const IteratorClass& itBegin, const IteratorClass& itEnd, ComparingFunctions f) {
if (itBegin != itEnd) {
for (auto it = itEnd - 1; it != itBegin; it--) {
if (f(*it))
return it;
}
//没找到,看看第一个元素是否符合
if (f(*itBegin))
return itBegin;
}
return itEnd;
}
/// <summary>
/// 标准库定义了名为partition的算法,它接受一个谓词,对容器内容进
/// 行划分,使得谓词为true的值会排在容器的前半部分,而使谓词为false的值会排
/// 在后半部分。算法返回一个迭代器,指向最后一个使谓词为true的元素之后的位置。
///
/// 例子:
///
/// vector<string> a = { "for","int","double","if" ,"throw" };
///
/// std::partition(a.begin(), a.end(), [](const string& s)->bool {
/// return s.size() >= 5;
/// });
///
/// _pn(a);
///
/// 输出:
///
/// a={"throw","double","int","if","for"}
///
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="ComparingFunctions"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-12 最后一修改时间:2024-10-12 (已测试)
template<typename IteratorClass, typename ComparingFunctions>
IteratorClass partition(IteratorClass itBegin, IteratorClass itEnd, ComparingFunctions f) {
//--------------------------------算法1
/*
IteratorClass itResult = itEnd;
while (itBegin != itEnd) {
if (!f(*itBegin)) { //还有优化可能,因为向后移时,itBegin每次都被比较
auto it = this->find_if(itBegin + 1, itEnd,f);
if (it != itEnd) {
this->Swap(itBegin, it);
itResult = itBegin; //保留最后一个位置
}
else {
return itResult;
}
}
itBegin++;
}
return itResult;
*/
//--------------------------------算法2 (结果跟std::partition相同)
if (itBegin != itEnd) {
IteratorClass itFindEnd = itEnd;
//itBegin != itFindEnd 很关键
for (; itBegin != itFindEnd; itBegin++) {
//执行次数与满足f条件的元素的个数相同
//std::cout << "*itBegin=" << *itBegin << "\n";
if (!f(*itBegin)) {
IteratorClass itFind = this->rfind_if(itBegin + 1, itFindEnd, f);
if (itFind != itFindEnd) {
//std::cout << "*itFindEnd=" << *itFind << "\n";
itFindEnd = itFind;
this->Swap(itBegin, itFind);
}else {
return itFindEnd;
}
}
}
//算法返回一个迭代器,指向最后一个使谓词为true的元素之后的位置。
return itFindEnd;
}
return itEnd;
}
///
/// <summary>
/// C++ 中的 for_each 是一个标准模板库 (STL) 算法,用于对容器中的每个元素执行指定的操作。
/// 这个操作可以是一个函数、一个函数对象或一个 Lambda 表达式。
///
/// 例子:
/// std::vector<int> nums = { 1, 2, 3, 4, 5 };
///
/// std::for_each(nums.begin(), nums.end(), [](int n) {
/// std::cout << n * 2 << "\t";
/// });
///
/// 输出:
///
/// 2 4 6 8 10
///
/// </summary>
/// <typeparam name="IteratorClass"></typeparam>
/// <typeparam name="FunctionClass"></typeparam>
/// <param name="itBegin"></param>
/// <param name="itEnd"></param>
/// <param name="f"></param>
/// <returns></returns>
/// 创建时间: 2024-10-13 最后一修改时间:2024-10-13 (已测试)
template<typename IteratorClass, typename FunctionClass>
FunctionClass for_each(const IteratorClass& itBegin, const IteratorClass& itEnd,
const FunctionClass &f) {
for (auto it = itBegin; it != itEnd; it++) {f(*it);}
return f;
}
///
}alg; //类实例
///
_LF_END_ //--------------------------- namespace lf
///