C++写自己需要的库“结束“

C++写自己需要的库“结束“,第1张

不想再写了,无非也是重复造轮子,写这个文件本身也是先提前造轮子,除了对于模板与重载的一些 *** 作,和新特性,个人认为大部分没太多技术含量,我们做昨天说了对于file_的更改,如下:

namespace file_ {			//写入数据做第一个参数表示此为template
	//获取当前时间的字符串
	std::string time_() {
		time_t timep;
		time(&timep);
		char tmp[256];
		strftime(tmp, sizeof(tmp), "%Y年%m月%d日_%H点%M分%S秒", localtime(&timep));
		std::string s{ tmp };
		return s;
	}
	//创建文件夹,默认在同级目录
	std::string newFolder(std::string name = time_(), std::string path = "") {
		std::string temp = "md ";
		temp += path;
		temp += name;
		//std::cout << "创建文件夹 " << temp << std::endl;
		system(temp.data());
		return temp.substr(3);
	}
	//删除文件夹
	std::string deleteFolber(std::string path) {
		std::string s = "rd ";
		system((s += path).data());
		return s.substr(3);
	}
	//以追加模式打开写文件
	std::string newWriteFile(std::string name = time_()+=".txt", std::string data = time_(), std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		ofs << data;
		ofs.close();
		return path;
	}
	//创建新的文件写入,一开始有就删除再创建
	void newlyFile(std::string name = time_()+=".txt", std::string data = time_(), std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		ofs << data;
		ofs.close();
	}
	
	//以追加模式打开写文件(template,重载)
	template
	std::string newWriteFile(T data, std::string name = time_() += ".txt", std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		ofs << data;
		ofs.close();
		return path;
	}
	//创建新的文件写入,一开始有就删除再创建(templat,重载)
	template
	void newlyFile(T data, std::string name = time_() += ".txt", std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		ofs << data;
		ofs.close();
	}
	//A开头表示数组,比如vector裸数组,array	其实按道理来说是可以和上面重载的,但是,之前想string对象版本会有问题,字符串优先匹配数组模板的重载,不想处理,懂吧
	// 以追加模式打开写文件(template,array)
	template
	void A_newWriteFile(T(&data)[size], std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//创建新的文件写入,一开始有就删除再创建(templat,array)
	template
	void A_newlyFile(T(&data)[size], std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}

	// app写file(template,vector)
	template
	void A_newWriteFile(std::vector data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < data.size(); i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//trunc写file(template,vector)
	template
	void A_newlyFile(std::vector data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < data.size(); i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}

	// app写file(template,array<>)
	template
	void A_newWriteFile(std::array data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//trunc写file(template,array<>)
	template
	void A_newlyFile(std::array data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//删除文件的数据
	void deleteData(std::string name ,std::string path = "") {
		path += name;
		std::ofstream ofs(path, std::ios::trunc);
		ofs.close();
	}
	//删除文件
	bool deleteFile(std::string path) {
		if (remove(path.data()) == 0) {
			//std::cout << "删除成功" << std::endl;
			return true;
		}
		else {
			std::cout << "删除失败" << std::endl;
			return false;
		}
	}
	//读取文件
	std::string readFile(std::string path) {
		std::ifstream ifs;
		ifs.open(path, std::ios::in);
		if (!ifs.is_open())
		{
			std::cout << "文件打开失败" << std::endl;
			return "";
		}
		std::string data{};
		while (ifs >> data);
		ifs.close();
		return data;
	}
	//打印输出文件内容
	void print(std::string path) {
		show_::print(readFile(path));
	}
	/*为什么读取的模板函数这么少?因为我发现貌似使用字符串是最方便的了,需要的话调用库函数进行转换即可,有一说一因为我加了空格这比较麻烦*/
}
#endif 

 也就造轮子加了普通数组重载与A开头的vector与array重载在一起,list的话暂时没有实现

1、为什么读取的模板函数这么少?因为我发现貌似使用字符串是最方便的了,需要的话调用库函数进行转换即可

2、为什么不提供二进制的方式?个人用的比较少,而且直接复制粘贴改一点即可

3、这个库总共的轮子有多少?代码有多少? 如下

#ifndef FUNC_H
#define FUNC_H
#pragma warning(disable:4996)
#include
#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace sort_ {
	void merge(int arr[], int start, int end, int mid, int* temp) {
		int i_start = start;
		int i_end = mid;
		int j_start = mid + 1;
		int j_end = end;

		int Length = 0;
		while (i_start <= i_end && j_start <= j_end) {
			if (arr[i_start] < arr[j_start])
				temp[Length++] = arr[i_start++];
			else
				temp[Length++] = arr[j_start++];
		}
		while (i_start <= i_end) {
			temp[Length++] = arr[i_start++];
		}
		while (j_start <= j_end) {
			temp[Length++] = arr[j_start++];
		}
		for (int i = 0; i < Length; i++) {
			arr[start + i] = temp[i];
		}
	}
	void mergeSort(int arr[], int start, int end, int* temp) {
		if (start >= end) {
			return;
		}
		int mid = (start + end) / 2;
		mergeSort(arr, start, mid, temp);
		mergeSort(arr, mid + 1, end, temp);
		merge(arr, start, end, mid, temp);
	}

	//快排
	template
	void quickSort(int left, int right, std::vector& arr) {
		if (left >= right)
			return;
		int i = left, j = right, base = arr[left];//取最左边的数为基准数
		while (i < j) {
			while (arr[j] >= base && i < j)
				j--;
			while (arr[i] <= base && i < j)
				i++;
			if (i < j) {
				std::swap(arr[i], arr[j]);
			}
		}
		arr[left] = arr[i];
		arr[i] = base;
		quickSort(left, i - 1, arr);
		quickSort(i + 1, right, arr);
	}
	template
	void quickSort(int left, int right, T arr[]) {
		if (left >= right)
			return;
		int i = left, j = right, base = arr[left];//取最左边的数为基准数
		while (i < j) {
			while (arr[j] >= base && i < j)
				j--;
			while (arr[i] <= base && i < j)
				i++;
			if (i < j) {
				std::swap(arr[i], arr[j]);
			}
		}
		arr[left] = arr[i];
		arr[i] = base;
		quickSort(left, i - 1, arr);
		quickSort(i + 1, right, arr);
	}

	//选择
	template//从小到大升序
	void selectSort(T arr[], int len) {
		for (int i = 0; i < len; i++) {
			int min = i;
			for (int j = i + 1; j < len; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			if (min != i) {
				std::swap(arr[min], arr[i]);
			}
		}
	}
	template
	void Inverted(T n[], int str, int end) {	//数组逆置
		if (str < end) {
			std::swap(n[str], n[end]);
			Inverted(n, str + 1, end - 1);
		}
		return;
	}
	template
	int sum(T n[], int start, int end) {//也可以使用accumulate算法
		if (start == end)return n[start];
		int mid = (start + end) >> 1;
		return sum(n, start, mid) + sum(n, mid + 1, end);
	}//二分递归,数组求和
	double average(int n[], int start, int end) {
		return sum(n, start, end) / static_cast(end + 1);
	}//二分递归,数组求和
	int fib(int n) {
		return n <= 2 ? 1 : fib(n - 1) + fib(n - 2);
	}//时间复杂度O(2^n),空间消耗很高
	int fib2(int n) {
		int f = 0, g = 1;
		while (0 < n--) {
			g = g + f;
			f = g - f;
		}
		return g;
	}//时间复杂度O(n),空间复杂度只需要O(1)
	//给数组移位,默认左移,时间复杂度O(n^2),很垃圾的遍历
	template
	void arrayShift(T(&v)[size], int n, bool k = true) {
		T temp;
		if (k) {
			for (int i = 0; i < n; i++) {
				temp = v[0];
				for (int j = 0; j < size - 1; j++) {
					v[j] = v[j + 1];
				}
				v[size - 1] = temp;
				temp = 0;
			}
		}
		else {
			for (int i = 0; i < n; i++) {
				temp = v[size - 1];
				for (int j = size - 1; j > 0; j--) {
					v[j] = v[j - 1];
				}
				v[0] = temp;
				temp = 0;
			}
		}
	}
	//重载版本array
	template
	void arrayShift(std::array&v, int n, bool k = true) {
		T temp;
		if (k) {
			for (int i = 0; i < n; i++) {
				temp = v[0];
				for (int j = 0; j < size - 1; j++) {
					v[j] = v[j + 1];
				}
				v[size - 1] = temp;
				temp = 0;
			}
		}
		else {
			for (int i = 0; i < n; i++) {
				temp = v[size - 1];
				for (int j = size - 1; j > 0; j--) {
					v[j] = v[j - 1];
				}
				v[0] = temp;
				temp = 0;
			}
		}
	}
	//其实,algorithm提供了rotate算法,很优质,我刚看见,那么这个重载用它吧,使用方式很简单,可以看253
	template
	void arrayShift(T&&begin,T&&mid,T&&end) {				//我们使用和库函数一样的调用方式,反正就是个套娃。
		std::rotate(begin,mid,end);
	}
	template	//普通数组版本删除元素,效率很低的方式,按照下标删除
	void erase(T(&v)[size], int lo)
	{
		for (int i = lo; i < size - 1; i++)
		{
			v[i] = v[i + 1];
			v[i + 1] = 0;
		}
	}
	template		//提供一个动态数组版本
	void earse(T*& p, int size, int lo)
	{
		T* temp = new T[size - 1];
		for (int i = lo; i < size - 1; i++)
		{
			p[i] = p[i + 1];
			p[i + 1] = 0;
		}
		std::copy_if(p, p + size, temp, [](T a) {return a != 0; });
		delete[]p;
		p = temp;
	}
	//去除有序序列重复项vector版本,低效方式,时间复杂度O(n^2)
	template
	int uniquify(std::vector& v) {
		int oldSize = v.size(); int i = 0;
		while (i < v.size() - 1) {
			if (v[i] == v[i + 1]) {
				v.erase(v.begin() + i);
			}
			else {
				i++;
			}
		}
		return oldSize - v.size();
	}
	//我们提供一个高明的O(n)的方式
	template
	int uniquify2(std::vector& v) {
		int i = 0, j = 0;
		while (++j < v.size())
			if (v[i] != v[j])v[++i] = v[j];
		v.resize(++i);
		return j - i;
	}
	//裸数组版本,把重复的替换为0放到后面,动态数组另说
	template
	int uniquify2(T(&v)[size]) {
		int i = 0, j = 0;
		while (++j < size)
			if (v[i] != v[j])v[++i] = v[j];
		std::fill(std::begin(v) + i, std::end(v), 0);
		return j - i - 1;
	}
}
namespace find_ {
	template
	int binarySearch(const std::vector& a, const Comparable& x)
	{
		int low = 0, hight = a.size()-1;
		while (low <= hight)
		{
			int mid = (low + hight) / 2;

			if (a[mid] < x) {
				low = mid + 1;
			}
			else if (a[mid] > x) {
				hight = mid - 1;
			}
			else
				return mid;		//找到的情况
		}
		return -1;
	}
	template
	int binarySearch(const Comparable *a, const Comparable x,Comparable len)
	{
		int low = 0, hight =len-1 ;
		while (low <= hight)
		{
			int mid = (low + hight) / 2;

			if (a[mid] < x) {
				low = mid + 1;
			}
			else if (a[mid] > x) {
				hight = mid - 1;
			}
			else
				return mid;		//找到的情况
		}
		return -1;
	}
}
namespace pow_ {
	double pow_(int x, size_t n)
	{
		if (n == 0)
			return 1;

		if (n == 1)
			return x;

		if (n % 2 == 0)
			return pow_(x * x, n / 2);
		else
			return pow_(x * x, n / 2) * x;
	}
	double pow_(int x, int n)
	{
		n = -n;
		return 1 / pow_(x, static_cast(n));
	}
}
namespace maxAmin {	//主要是之前没有注意algorithm提供了这个算法std::cout<<*std::max_element(std::begin(num), std::end(num));,min也是同理,注意这个函数的返回值是地址,需要*取地址即可
	template
	auto max(T(&n)[size]) {
		T Max{};
		for (size_t i = 0; i < size; i++) {
			if (n[i] > Max)Max = n[i];
		}
		return Max;
	}
	template
	auto max(std::vectorn) {
		T Max{};
		for (size_t i = 0; i < n.size(); i++) {
			if (n[i] > Max)Max = n[i];
		}
		return Max;
	}
	template
	auto min(T(&n)[size]) {
		T Min = n[0];
		for (size_t i = 1; i < size; i++) {
			if (n[i] < Min)Min = n[i];
		}
		return Min;
	}
	template
	auto min(std::vectorn) {
		T Min = n[0];
		for (size_t i = 1; i < n.size(); i++) {
			if (n[i] < Min)Min = n[i];
		}
		return Min;
	}
}
namespace show_ {
	template
	void print(const T(&n)[i], const std::string s=" ") {
		std::copy(std::begin(n),std::end(n), std::ostream_iterator(std::cout, s.data()));
		std::cout << std::endl;
	}
	template
	void print(const std::array v, const std::string s = " ") {
		std::copy(std::begin(v), std::end(v), std::ostream_iterator(std::cout, s.data()));
		std::cout << std::endl;
	}
	void print(const char* s) {
		std::cout << s << std::endl;											//重载特殊情况,字符串常量输出
	}
	template
	void print(const std::vectorn,const std::string s=" ") {
		std::copy(std::begin(n), std::end(n), std::ostream_iterator(std::cout, s.data()));
		std::endl(std::cout);
	}
	template
	void print(T v) {
		std::cout << v << std::endl;
	}
	template
	void print(const std::list& L,std::string s=" ") {
		for (auto it = L.begin(); it != L.end(); it++) {										//list容器版本
			std::cout << *it << s;
		}
		std::cout << std::endl;
	}
	template
	void print(_Type1 _Value1, _Type2 _Value2, _Types... _Values)//c++17折叠表达式
		requires (sizeof...(_Types) > 0 || (!std::is_same_v && !std::is_same_v))//requires是c++20的
	{
		std::cout << _Value1 << ' ' << _Value2 << " ";
		((std::cout << _Values ), ...);
	}
	namespace object {			//这真是无奈之举,这个匹配,object命名空间内的除了遍历vector和array的数组外,标准数据类型直接打印也可行
		template
		std::ostream& operator<<(std::ostream& os, const std::vector& data)
		{
			for (auto& str : data)
			{
				os << str<<" ";
			}
			return os;
		}
		template
		std::ostream& operator<<(std::ostream& os, const std::array& data)
		{
			for (auto& str : data)
			{
				os << str<<",";
			}
			return os;
		}
		void print() {}
		template
		void print(T first, Types...args) {
			std::cout << first << '\n';
			print(args...);
			return;
		}
	}
	namespace range {	//没办法重载多了就是匹配问题,我能这里使用c++20的range
		void print_impl(std::ostream& out, std::ranges::range auto&& r)
		{
			for (auto&& elem : r)
			{
				out << elem << " ";
			}
			std::cout << std::endl;
		}
		void print_impl(std::ostream& out, auto&& elem)
		{
			out << elem << " ";
			std::cout << std::endl;
		}
		void print(auto&&...args)
		{
			(print_impl(std::cout, args), ...);
		}
	}
	namespace rangeClass {		//也可以写成一个类,主要是为了防止让print_impl暴露在外部接口,因为print同名的缘故所以我们无法写在一起
		class print {
		public:
			void operator()(auto&&...args)
			{
				(print_impl(std::cout, args), ...);
			}
		private:
			void print_impl(std::ostream& out, std::ranges::range auto&& r)
			{
				for (auto&& elem : r)
				{
					out << elem << " ";
				}
				std::cout << std::endl;
			}
			void print_impl(std::ostream& out, auto&& elem)
			{
				out << elem << " ";
				std::cout << std::endl;
			}
		};
	}
}
namespace file_ {			//写入数据做第一个参数表示此为template
	//获取当前时间的字符串
	std::string time_() {
		time_t timep;
		time(&timep);
		char tmp[256];
		strftime(tmp, sizeof(tmp), "%Y年%m月%d日_%H点%M分%S秒", localtime(&timep));
		std::string s{ tmp };
		return s;
	}
	//创建文件夹,默认在同级目录
	std::string newFolder(std::string name = time_(), std::string path = "") {
		std::string temp = "md ";
		temp += path;
		temp += name;
		//std::cout << "创建文件夹 " << temp << std::endl;
		system(temp.data());
		return temp.substr(3);
	}
	//删除文件夹
	std::string deleteFolber(std::string path) {
		std::string s = "rd ";
		system((s += path).data());
		return s.substr(3);
	}
	//以追加模式打开写文件
	std::string newWriteFile(std::string name = time_()+=".txt", std::string data = time_(), std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		ofs << data;
		ofs.close();
		return path;
	}
	//创建新的文件写入,一开始有就删除再创建
	void newlyFile(std::string name = time_()+=".txt", std::string data = time_(), std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		ofs << data;
		ofs.close();
	}
	
	//以追加模式打开写文件(template,重载)
	template
	std::string newWriteFile(T data, std::string name = time_() += ".txt", std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		ofs << data;
		ofs.close();
		return path;
	}
	//创建新的文件写入,一开始有就删除再创建(templat,重载)
	template
	void newlyFile(T data, std::string name = time_() += ".txt", std::string path = "") {
		path += name;
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		ofs << data;
		ofs.close();
	}
	//A开头表示数组,比如vector裸数组,array	其实按道理来说是可以和上面重载的,但是,之前想string对象版本会有问题,字符串优先匹配数组模板的重载,不想处理,懂吧
	// 以追加模式打开写文件(template,array)
	template
	void A_newWriteFile(T(&data)[size], std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//创建新的文件写入,一开始有就删除再创建(templat,array)
	template
	void A_newlyFile(T(&data)[size], std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}

	// app写file(template,vector)
	template
	void A_newWriteFile(std::vector data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < data.size(); i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//trunc写file(template,vector)
	template
	void A_newlyFile(std::vector data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < data.size(); i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}

	// app写file(template,array<>)
	template
	void A_newWriteFile(std::array data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::app);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//trunc写file(template,array<>)
	template
	void A_newlyFile(std::array data, std::string path = time_() += ".txt") {
		std::ofstream ofs;
		ofs.open(path, std::ios::trunc);
		for (int i = 0; i < size; i++)ofs << data[i] << " ";
		ofs << std::endl;
		ofs.close();
	}
	//删除文件的数据
	void deleteData(std::string name ,std::string path = "") {
		path += name;
		std::ofstream ofs(path, std::ios::trunc);
		ofs.close();
	}
	//删除文件
	bool deleteFile(std::string path) {
		if (remove(path.data()) == 0) {
			//std::cout << "删除成功" << std::endl;
			return true;
		}
		else {
			std::cout << "删除失败" << std::endl;
			return false;
		}
	}
	//读取文件
	std::string readFile(std::string path) {
		std::ifstream ifs;
		ifs.open(path, std::ios::in);
		if (!ifs.is_open())
		{
			std::cout << "文件打开失败" << std::endl;
			return "";
		}
		std::string data{};
		while (ifs >> data);
		ifs.close();
		return data;
	}
	//打印输出文件内容
	void print(std::string path) {
		show_::print(readFile(path));
	}
	/*为什么读取的模板函数这么少?因为我发现貌似使用字符串是最方便的了,需要的话调用库函数进行转换即可,有一说一因为我加了空格这比较麻烦*/
}
#endif 

个人对于一些代码不喜欢换行,所以有些地方有点长。

轮子视图如下,不算很多,估计过几天我就觉得自己的代码写的很烂了(虽然现在觉得)

 总计6个命名空间,还有两个命名空间嵌套在show_内,不做计算,1个类,函数和模板我懒得数数,五十多个,还有四个运算符重载

 环境:MSVC(VS 2022企业版) x64 debug C++20 未开启优化

先这样吧,不想花太多时间,最近在写数据结构,在这个库内也能看出在强调效率与时间复杂度,空间复杂度,一些常用的归并,快排,我没有全部写出来,参考即可。C++的泛型编程大大提高了代码复用性,C++17所更新的折叠表达式让我们使用可变参数模板的使用不必像C++11一样使用低效的递归解包。C++20所新增的特性让我们得以让print的可变参数与其他6个重载正常使用,至于使用了特殊的range之类的方式,就目前而言,就算是ISO委员会的代码也无法避免这些问题,可变参数的匹配优先级过高。所以print的重载做了很多的妥协,有望在后续的C++版本或本人实力足以解决这些问题的使用再来处理。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/676041.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存