ACM模板三:二分、字典树、字符串、几何、DP

该文提供了一系列C++实现的算法和数据结构,包括二分查找、字典树(Trie)、字符串处理(如括号匹配、分割、拼接等)、几何问题(如斜率、距离、点与圆的关系等)、类型转换及累积计算、动态规划问题(如最长上升子序列、最长等差数列)。代码结构清晰,易于理解,适用于学习和参考。

目录

〇,全文说明、宏定义代码

一,二分查找

1,代码

2,测试代码

二,类型计算、字典树

1,代码

2,测试代码

三,字符串处理、串匹配

1,代码

2,测试代码

四,几何

1,代码

2,测试代码

五,类型提升、数据结构转换、累积计算、动态规划

1,代码

2,测试代码


〇,全文说明、宏定义代码

类里面和宏定义处都有接口注释,因为宏不体现具体参数,所以注释以类里面的为准。

代码工程结构:

  • 每一章的第一节《代码》可以独立编译运行(本地要加LOCAL宏)
  • 每一章的第二节《测试代码》搭配第〇章的代码和本章第一节的代码可以编译运行并测试成功
  • 所有模板文章的第〇章的代码和其他章第一节的《代码》全部汇总起来可以编译运行

宏定义代码:

// #define OLD_PLATFORM //旧版本C++就打开这个宏

///(1)二分查找///
// Bsearch 略。寻找[low,high]中最小的满足Ok条件的数,low<=high,返回值范围是[low,high+1]

///(2.1)类型计算///
#define MinValue BasicTypeOpt::minValue//类型最小值
#define ValueNum BasicTypeOpt::valueNum//类型数量

///(2.2)字典树///
// Trie 略。字典树

///(3.1)基础字符串处理///
#define	StringSplit StringOpt::stringSplit//把字符串按照分隔符拆开成若干字符串
#define	StringMatchSplit StringOpt::stringMatchSplit//字符串括号分割,第一行是括号外子串集,第二行是括号内子串集,不含最外层括号
#define StringJoin StringOpt::stringJoin//把字符串列表拼接起来,用分隔符隔开
#define CharToString StringOpt::charToString//char数组/列表转化成string
#define StringToChar StringOpt::stringToChar//string转化成char数组
#define StringToCharVec StringOpt::stringToCharVec//string转化成char列表

///(3.2)子串匹配///
#define GetSameSubStr RabinKarp::getSameSubStr//获得任意一个长为len的重复子串,2个子串可以重叠
#define GetlongestDupSubstring LongestDupSubstring().getlongestDupSubstring//获得任意一个最长重复子串
//KMP 略
//OrderMatch 略。偏序匹配 

///(4)几何///
#define Slope GeometryBase::slope  //求2点斜率
#define PointDistance GeometryBase::pointDistance //求2点距离
#define InCircle GeometryBase::inCircle //判断点是否在圆内
#define IsParallels GeometryBase::isParallels // 两直线是否平行
#define IsSameLine GeometryBase::isSameLine // 两直线是否重叠
#define IntersectionLineAndLine GeometryBase::intersectionLineAndLine // 两直线交点,仅在不平行时才能调用
#define PointInSegment GeometryBase::pointInSegment //已知线段se和点p在一条直线上,判断p是否在se之间(包括se)
#define IsSameSide GeometryBase::isSameSide//2点是否在直线同侧,包括点在直线上也算
#define IsPointInLine GeometryBase::isPointInLine//点是否在直线上
#define GetPosStatus GeometryBase::getPosStatus // 求凸多边形和直线的4种位置关系,如果相交则输出交点
#define GetMaxSlope GeometryBase::getMaxSlope //求点集中任意两点斜率的最大值
#define GetMinSlope GeometryBase::getMinSlope //求点集中任意两点斜率的最小值
// Andrew 略。 求凸包
#define MinMaxWithSlope Geometry().minMaxWithSlope //输入上(下)凸包,从左往右,type为max(min),求y-kx的最大(小)值在哪个点

///(5.1)类型处理///
// UpperType 略。类型提升

///(5.2)数据结构转换///
#define VecTrans BasicOpt::vecTrans//把列表的每个元素进行p转换,p:T1->T2
#define MapTrans BasicOpt::mapTrans//把map的每个pair进行p转换,p:<T0,T1>->T2
#define MapTransToVec BasicOpt::mapTransToVec//把map的每个pair进行p转换,p:<T0,T1>->T2
#define MapToPairs BasicOpt::mapToPairs//把map转成pair数组
#define DrawFirst BasicOpt::drawFirst//提取pair数组的first
#define DrawSecond BasicOpt::drawSecond//提取pair数组的second
#define GetMapFirst BasicOpt::getMapFirst//提取map的first
#define GetMapSecond BasicOpt::getMapSecond//提取map的second
#define StackToVec BasicOpt::stackToVec//栈转化成数组
#define QueToVec BasicOpt::queToVec//队列转化成数组
#define VecToArr BasicOpt::vecToArr//vector转数组
#define GetNumFromId BasicOpt::getNumFromId//把id数组(一维或二维)转化为对应的数v[id]
#define VectorToMap BasicOpt::vectorToMap//把v1和v2 匹配转化成1个map<v1,v2>
#define VmToVector BasicOpt::vmToVector//1个vector加1个map转化成map[vector]

///(5.3)累积计算///
#define GetMultiOpt MultiOpt::getMultiOpt //获取累积计算结果,p:<T2,T>->T2
#define GetVecMax MultiOpt::getVecMax //获取vector中最大值
#define GetVecMax2 MultiOpt::getVecMax2 //获取二维vector中最大值
#define GetVecMin MultiOpt::getVecMin //获取vector中最小值
#define GetVecMin2 MultiOpt::getVecMin2 //获取二维vector中最小值
#define GetVecSum MultiOpt::getVecSum //获取所有元素之和
#define TransSum MultiOpt::transSum//进行p转换并求和,返回p(v[0])+p(v[1])+...
#define NumInVec2D MultiOpt::numInVec2D//计算二维列表的元素数

///(5.4)动态规划///
// ArrayDP 数列DP
// DP_LengthOfLIS 最长上升子序列
// DP_lengthOfEqualDif 最长等差数列
#define MaxSubArrayFromEver DP_MaxSubArray::maxSubArrayFromEver//求以每个元素开头的最大子段和
#define MaxSubArray DP_MaxSubArray::maxSubArray//求最大子段和

一,二分查找

1,代码


template<typename T>
class Bsearch //寻找[low,high]中最小的满足isOk条件的数,low<=high,返回值范围是[low,high+getGap()]
{
public:
	T find(T low, T high)
	{
		if (!isOk(high))return high + getGap(high);
		if (isOk(low))return low;
		T mid;
		while (high - low > getGap(low)) {
			mid = (high + low) / 2;
			if (isOk(mid))high = mid;
			else low = mid;
		}
		return high;
	}
private:
	virtual bool isOk(T x) //若isOk(x)且!isOk(y)则必有y<x
	{
		return x > 0;
	}
	int getGap(int) {
		return 1;
	}
	int getGap(long long) {
		return 1;
	}
	double getGap(double) {
		return 0.00000001;
	}
};

2,测试代码

#define EXPECT_EQ(a,b) if(a!=b){cout<<"ERROR!!!!!!!!!\n";return false;}

bool testBsearch()//待完善
{
	Bsearch<int>{};
	return true;
}

int main()
{
	if (testBsearch())cout << "test succ!";
	return 0;
}

二,类型计算、字典树

1,代码


class BasicTypeOpt {
public:
	static char minValue(char)
	{
		return 'a';
	}
	static int minValue(int)
	{
		return 0;
	}
	static int valueNum(char)
	{
		return 26;
	}
	static int valueNum(int)
	{
		return 10;
	}
};
template<typename T>
class Trie : public BasicTypeOpt
{
public:
	vector<vector<int>>v;
	map<int, int>isEnd;//以任一节点作为尾节点的数目(不一定是叶子节点)
	map<int, int>deep;//任一节点的深度
	Trie()
	{
		auto valNum = valueNum(T{});
		v.push_back(vector<int>(valNum + 1, 0));
	}
	void push(const T* s, int len, int value = 0)
	{
		auto minVal = minValue(T{});
		auto valNum = valueNum(T{});
		int j = 0;
		for (int i = 0; i < len; i++)
		{
			if (v[j][s[i] - minVal + 1] == 0)
			{
				v[j][s[i] - minVal + 1] = v.size();
				v.push_back(vector<int>(valNum + 1, 0));
				deep[v.size() - 1] = i + 1;
			}
			j = v[j][s[i] - minVal + 1];
		}
		v[j][0] = value;
		isEnd[j]++;
	}
	int find(const T* s, int len, int& maxDeep, vector<int>& ends)//deep是搜到的最大长度,ends是路过哪些end节点
	{
		auto minVal = minValue(T{});
		int j = 0;
		maxDeep = 0;
		for (int i = 0; i < len; i++)
		{
			if (v[j][s[i] - minVal + 1] == 0)return 0;
			j = v[j][s[i] - minVal + 1];
			maxDeep++;
			if (isEnd[j])ends.push_back(j);
		}
		return v[j][0];
	}
	int find(const T* s, int len)
	{
		int maxDeep;
		vector<int>ends;
		return find(s, len, maxDeep, ends);
	}
};

2,测试代码

#define EXPECT_EQ(a,b) if(a!=b){cout<<"ERROR!!!!!!!!!\n";return false;}

bool testBasicTypeOpt()
{
	EXPECT_EQ(MinValue('?'), 'a');
	return true;
}
bool testTrie()//待完善
{
	Trie<int>{};
	return true;
}

int main()
{
	if (testBasicTypeOpt() && testTrie())cout << "test succ!";
	return 0;
}

三,字符串处理、串匹配

1,代码


class StringOpt
{
public:
	//把字符串按照若干分隔符拆开成若干字符串
	static vector<string> stringSplit(string text, map<char, int>& splitChar)
	{
		vector<string>v;
		v.clear();
		int low = 0, key =
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值