03c++重载运算符

news2025/1/20 1:42:28

1、深入理解new和delete原理

#include<iostream>
using namespace std;


/*
new 和 delete
1、malloc和new的区别 new = 内存开辟+构造函数
2、free和 delete的区别 delete = 内存回收+析构函数
开辟失败malloc返nullptr ,new抛出bad_alloc异常

new->operator new
delete ->operator delete
*/

//先调用operator new开辟内存空间然后调对象的构造函数
//void* operator new(size_t size)
//{
//	void* p = malloc(size);
//	if (p == nullptr)
//		throw bad_alloc();
//	cout << "operator new  " << p << endl;
//	return p;
//}
调用delete p;调用p指向对象的析构函数,在调用operator delete释放内存空间
//
//void operator delete(void* ptr)
//{
//	cout << "operator delete  " << ptr << endl;
//
//	free(ptr);
//}

//先调用operator new开辟内存空间然后调对象的构造函数

/*
new和delete能混用吗? 为什么区分单个元素和数组的内存分配和释放呢?
new delete
new[] delete[]
对于普通的编译器内置类型new/delete[]  new[]/delete可以混用

自定义的类型有析构函数,为了正确调用,在开辟对象数组的时候会多开辟四个字节,记录对象的个数
*/
void* operator new[](size_t size)
	{
		void* p = malloc(size);
		if (p == nullptr)
			throw bad_alloc();
		cout << "operator new addr[]" << p << endl;
		return p;
	}
	//调用delete p;调用p指向对象的析构函数,在调用operator delete释放内存空间

		void operator delete[](void* ptr)
		{
			cout << "operator delete addr[]" << ptr << endl;

			free(ptr);
		}



		class Test
		{
		public:
			Test(int data = 10)
			{
				cout << "Test()" << endl;
			}
			~Test()
			{

				cout << "~Test()" << endl;
			}

		};
		int main()
		{
			//try
			//{
			//	int* p = new int;
			//	delete p;

			//	int* q = new int[10];
			//	delete[]q;

			//}
			//catch (const bad_alloc& err)
			//{
			//	cerr << err.what() << endl;
			//}

			//Test* p1 = new Test();
			//delete[]p1; //报错


			Test* p2 = new  Test[5]; //delete p2;错误 Test[0]析构,直接俄free(p2)
			cout << "p2: " << p2 << endl;
			delete[]p2;
			return 0;
		}

在这里插入图片描述

2、new和delete重载对象池应用在这里插入图片描述

在这里插入图片描述

#include<iostream>
using namespace std;


/*运算符的重载:成员方法、全局方法
* 内存池 进程池 线程池 连接池 对象池
*/

template<typename T>
class Queue
{
public:
	Queue()
	{
		_front = _rear = new QueueItem();

	}
	~Queue()
	{
		QueueItem* cur = _front;
		while (cur != nullptr)
		{
			_front = _front->_next;
			delete cur;
			cur = _front;
		}
	}

	void push(const T& val)
	{
		QueueItem* item = new QueueItem(val);
		_rear->_next = item;
		_rear = item;
	}
	void pop()
	{
		if (empty())
		{
			return;
		}
		QueueItem* first = _front->_next;
		_front->_next = first->_next;
		if (_front->_next == nullptr)
		{
			_rear = _front;
		}
		delete first;
	}

	T front()const
	{
		return   _front->_next->_data;

	}

	bool empty() const { return _rear == _front; }
private:
	struct QueueItem //产生一个QueueItem的对象池(10000个节点)
	{
		//给QueueItem提供自定义的内存管理
		QueueItem(T data = T()) :_data(data), _next(nullptr) {}

		void* operator new (size_t size)
		{
			if (_itempool == nullptr)
			{
				_itempool = (QueueItem*)new char[POOL_ITEM_SIZE * sizeof(QueueItem)]; //开辟内存
				QueueItem* p = _itempool;
				for (; p < _itempool + POOL_ITEM_SIZE - 1; ++p)
				{
					p->_next = p + 1;
				}
				p->_next = nullptr;
			}
			QueueItem* p = _itempool;
			_itempool = _itempool->_next;
			return p;

		}
		void operator delete(void* ptr)
		{
			QueueItem* p = (QueueItem*)ptr;
			p->_next = _itempool;
			_itempool = p;
		}
		T _data;
		QueueItem* _next;
		static const int POOL_ITEM_SIZE = 1000000;
		static QueueItem* _itempool; //指向头节点的指针
	};

	QueueItem* _front; //指向头节点
	QueueItem* _rear; //指向队尾
};


template<typename T>
typename Queue<T>::QueueItem* Queue<T>::QueueItem::_itempool = nullptr;
int main()
{
	Queue<int> que;
	for (int i = 0; i < 10000; i++)
	{
		que.push(i);
		que.pop();
	}
	cout << que.empty() << endl;
	return 0;
}

3、运算符重载 复数类

#include<iostream>
using namespace std;

/*
* C++运算符重载:使得对象的运算表现得和内置类型一样
*/

//复数类
class CComplex
{
public:
	CComplex(int r = 0, int i = 0)
		:mreal(r), mimage(i) {}
	//指导编译器如何做加法操作
	CComplex& operator+(const CComplex& comp)
	{
		this->mimage += comp.mimage;
		this->mreal += comp.mreal;
		return *this;
	}

	CComplex& operator+(const int& b)
	{
		this->mreal += b;
		return *this;
	}


	CComplex& operator++()
	{
		mreal += 1;
		mimage += 1;
		return *this;
	}

	CComplex& operator++(int)
	{
		CComplex tmp = *this;
		this->mimage++;
		this->mreal++;
		return tmp;
	}
	friend CComplex& operator+(const int& a, CComplex& comp);
	friend ostream& operator<<(ostream& os, const CComplex& comp);
	void show() { cout << "real: " << mreal << " image: " << mimage << endl; }
private:
	int mreal;
	int mimage;
};

CComplex& operator+(const int& a, CComplex& comp)
{
	comp.mreal += a;
	return comp;
}

ostream& operator<<(ostream& os, const CComplex& comp)
{
	os << "real: " << comp.mreal << " image: " << comp.mimage << endl;
	return os;
}
int main()
{
	CComplex comp1(10, 10);
	CComplex comp2(20, 20);
	//CComplex comp3 = comp1 + comp2;
	CComplex comp3 = comp1.operator+(comp2);
	comp3.show();

	comp3.operator+(10);
	comp3.show();

	comp3 = 15 + comp3;
	comp3.show();

	CComplex comp4 = comp3++;  //operator++()前置++ operator++(int)后置++
	comp4.show();
	++comp4;
	comp4.show();
	cout << comp4 << endl;
	return 0;
}

4、string类的实现

#include<iostream>
using namespace std;
#include<string>
//自己实现string类
class String
{
public:
	String(const char* p = nullptr)
	{
		if (p != nullptr)
		{
			_str = new char[strlen(p) + 1];
			strcpy_s(_str, strlen(p) + 1, p);

		}
		else
		{
			_str = new char[1];
			*_str = '\0';
		}
	}
	~String()
	{
		delete[] _str;
		_str = nullptr;
	}

	String(const String& str)
	{
		_str = new char[strlen(str._str) + 1];
		strcpy_s(_str, strlen(str._str) + 1, str._str);
	}

	String& operator=(const String& src)
	{
		if (this == &src)
		{
			return *this;
		}
		delete[]_str;
		_str = new char[strlen(src._str) + 1];
		strcpy_s(_str, strlen(src._str) + 1, src._str);
		return *this;

	}
	bool operator>(const String& str)const
	{
		return strcmp(_str, str._str) > 0;
	}
	bool operator<(const String& str)const
	{
		return strcmp(_str, str._str) < 0;
	}
	bool operator==(const String& str)const
	{
		return strcmp(_str, str._str) == 0;
	}

	char& operator[](int index)
	{
		return _str[index];
	}

	char& operator[](int index)const
	{
		return _str[index];
	}

	int length()const { return strlen(_str); }
	const char* c_str() const { return _str; }
	friend String operator+(const String& lhs, const String& rhs);
public:
	ostream& operator<<(ostream& os)
	{
		os << _str;
		return os;
	}

private:
	char* _str;
};

// 重载加法运算符
String operator+(const String& lhs, const String& rhs)
{
	String tmp;
	delete[] tmp._str;
	tmp._str = new char[strlen(lhs._str) + strlen(rhs._str) + 1];
	strcpy_s(tmp._str, strlen(lhs._str) + 1, lhs._str);
	strcat_s(tmp._str, strlen(lhs._str) + strlen(rhs._str) + 1, rhs._str);
	return tmp;
}
int main()
{
	String a("aaa");
	String b("ccc");
	a.operator<<(cout) << endl;
	(a + b).operator<<(cout) << endl;
	//string str1;
	//string str2 = "aaa";
	//string str3 = "bbbb";
	//string str4 = str2 + str3;
	//cout << str4 << endl;


	return 0;
}

5、迭代器

在这里插入图片描述

#include<iostream>
using namespace std;
#include<string>
//自己实现string类 以及迭代器
class String
{
public:
	String(const char* p = nullptr)
	{
		if (p != nullptr)
		{
			_str = new char[strlen(p) + 1];
			strcpy_s(_str, strlen(p) + 1, p);

		}
		else
		{
			_str = new char[1];
			*_str = '\0';
		}
	}
	~String()
	{
		delete[] _str;
		_str = nullptr;
	}

	String(const String& str)
	{
		_str = new char[strlen(str._str) + 1];
		strcpy_s(_str, strlen(str._str) + 1, str._str);
	}

	String& operator=(const String& src)
	{
		if (this == &src)
		{
			return *this;
		}
		delete[]_str;
		_str = new char[strlen(src._str) + 1];
		strcpy_s(_str, strlen(src._str) + 1, src._str);
		return *this;

	}
	bool operator>(const String& str)const
	{
		return strcmp(_str, str._str) > 0;
	}
	bool operator<(const String& str)const
	{
		return strcmp(_str, str._str) < 0;
	}
	bool operator==(const String& str)const
	{
		return strcmp(_str, str._str) == 0;
	}

	char& operator[](int index)
	{
		return _str[index];
	}

	char& operator[](int index)const
	{
		return _str[index];
	}

	int length()const { return strlen(_str); }
	const char* c_str() const { return _str; }
	friend String operator+(const String& lhs, const String& rhs);

	//提供迭代器
	class iterator
	{
	public:
		iterator(char* p = nullptr) :_p(p) {}
		bool operator!=(const iterator& it)
		{
			return _p != it._p;
		}
		void  operator++()
		{
			++_p;
		}
		char& operator*() { return *_p; }
	private:
		char* _p;
	};
	iterator begin() { return iterator(_str); }
	iterator end() { return iterator(_str + length()); }
public:
	ostream& operator<<(ostream& os)
	{
		os << _str;
		return os;
	}

private:
	char* _str;
};

// 重载加法运算符
String operator+(const String& lhs, const String& rhs)
{
	String tmp;
	delete[] tmp._str;
	tmp._str = new char[strlen(lhs._str) + strlen(rhs._str) + 1];
	strcpy_s(tmp._str, strlen(lhs._str) + 1, lhs._str);
	strcat_s(tmp._str, strlen(lhs._str) + strlen(rhs._str) + 1, rhs._str);
	return tmp;
}
int main()
{


	String s("hello world!");
	for (String::iterator it = s.begin(); it != s.end(); ++it)
	{
		cout << *it << " ";
	}

	//c++11
	cout << endl;
	for (char ch : s)
	{
		cout << ch << " ";
	}

	return 0;
}

6、Vector迭代器

#include<iostream>
using namespace std;



/*
template <class _Ty,
	class _Alloc = allocator<_Ty>>
	class Vector
	容器的空间配置器allocator做四件事情 内存开辟 内存释放 对象构造 对象析构
*/

//定义容器的空间配置器,和c++标准库的allocator实现一样
template<typename T>
class Allocator
{
public:
	T* allocate(size_t size) //负责内存开辟
	{
		return (T*)malloc(sizeof(T) * size);

	}

	void deallocate(void* p) //负责内存释放
	{
		free(p);
	}

	void construct(T* p, const T& val) //负责对象构造
	{
		new (p) T(val);//定位new
	}
	void destroy(T* p)//负责对象析构
	{
		p->~T();//代表了T类型的析构函数
	}
};
template<typename T, typename Alloc = Allocator<T>>
class Vector
{
public:
	Vector(int size = 10)
	{
		//需要把内存开辟和对象构造分开处理
		//_first = new T[size];
		_first = _allocator.allocate(size);

		_last = _first;
		_end = _first + size;
	}

	~Vector()
	{
		//delete[]_first;
		//析构有效的元素,然后释放_first指针指向的堆内存
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作
		}
		_allocator.deallocate(_first);//释放堆上的数组内存
		_first = _last = _end = nullptr;
	}

	Vector(const Vector<T>& rhs)
	{
		int size = rhs._end - rhs._first;
		//_first = new T[size]; //空间大小
		_first = _allocator.allocate(size);
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}

		_last = _first + len;
		_end = _first + size;
	}
	Vector<T>& operator=(const Vector<T>& rhs) //拷贝构造
	{
		if (this == &rhs)return *this;
		//delete[] _first;
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p); //把first指针指向的数组的有效元素进行析构操作
		}
		_allocator.deallocate(_first);//释放堆上的数组内存

		int size = rhs._end - rhs._first;
		int len = rhs._last - rhs._first;
		for (int i = 0; i < len; i++)
		{
			//_first[i] = rhs._first[i];
			_allocator.construct(_first + i, rhs._first[i]);
		}
		_last = _first + len;
		_end = _first + size;
		return *this;
	}

	void push_back(const T& val)
	{
		if (full())
		{
			expand();
		}
		//*_last = val;
		_allocator.construct(_last, val);
		_last++;
	}

	void pop_back()
	{
		if (empty())
		{
			return;
		}
		//--_last;
		--_last;
		_allocator.destroy(_last);
	}
	T back()const //返回容器末尾的元素值
	{
		return *(_last - 1);
	}

	bool full()const { return _last == _end; }
	bool empty()const { return _first == _last; }
	int size()const { return _last - _first; }

	T& operator[](int index)
	{
		if (index < 0 || index >= size())
		{
			throw "outofrangeException";
		}
		return _first[index];
	}
	//迭代器一般是现成容器的嵌套类型
	class iterator
	{
	public:
		iterator(T* _ptr = nullptr)
			:_ptr(_ptr) {}

		bool operator!= (const iterator& it)const
		{
			return _ptr != it._ptr;

		}
		void operator++()
		{
			_ptr++;
		}
		T& operator*() { return *_ptr; } //解引用读取与赋值
		const T& operator*() const { return *_ptr; } //解引用读取与赋值
	private:
		T* _ptr;
	};
	//需要给容提供begin和end的方法
	iterator begin() { return iterator(_first); }
	iterator end() { return iterator(_last); }

private:

	void expand()
	{
		int _size = _end - _first;
		//T* tmp = new T[_size * 2];
		T* tmp = _allocator.allocate(2 * _size);
		for (int i = 0; i < _size; i++)
		{
			//tmp[i] = _first[i];
			_allocator.construct(tmp + i, _first[i]);
		}
		//delete[]_first;
		for (T* p = _first; p != _last; p++)
		{
			_allocator.destroy(p);
		}
		_allocator.deallocate(_first);
		_first = tmp;
		_last = _first + _size;
		_end = _first + 2 * _size;
	}
	T* _first; //指向数组的起始的位置
	T* _last; //指向数组有效元素的后继位置
	T* _end; //指向数组空间的后继位置

	Alloc _allocator;//定义i容器中的空间配置项

};
//容器空间分配器
class Test
{
public:
	Test() { cout << "test()" << endl; }
	~Test() { cout << "~test()" << endl; }
	Test(const Test&) { cout << "Test(const Test&)" << endl; }
};

int main()
{
	Vector<int>vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}

	Vector<int>::iterator it = vec.begin();
	for (; it != vec.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

7、迭代器失效:

#include<iostream>
#include<vector>
using namespace std;


/*
迭代器的失效问题?
1、迭代器为什么会失效?
a、容器调用erase方法后,当前位置到容器末尾元素的所有迭代器全部失效了
b、容器调用insert后,当前位置到容器末尾元素的所有迭代器全部失效了
	迭代器依然有效 迭代器全部失效

*/
int main()
{
	vector<int> vec;
	for (int i = 0; i < 20; i++)
	{
		vec.push_back(rand() % 100 + 1);
	}
	for (int v : vec)
	{
		cout << v << " ";
	}
	cout << endl;
	auto it = vec.begin();
	for (; it != vec.end(); it++)
	{
		if (*it % 2 == 0)
		{
			it = vec.insert(it, *it - 1);
			++it;
		}
	}
	for (int v : vec)
	{
		cout << v << " ";
	}
	cout << endl;
	//给vec容器中所有的偶数前面添加一个小于偶数值1的数字
	//auto it = vec.begin();
	//for (; it != vec.end(); it++)
	//{
	//	if (*it % 2 == 0)
	//	{
	//		//这里的迭代器在第一次insert之后就失效了
	//		vec.insert(it, *it - 1);
	//		//it += 2;
	//		//break;
	//	}
	//}

#if 0
	auto it = vec.begin();
	for (; it != vec.end(); it++)
	{
		if (*it % 2 == 0)
		{
			vec.erase(it); //迭代器失效的问题 第一次调用erase以后迭代器就失效了
			//break;
		}
	}
#endif 
	return 0;
	}

在这里插入图片描述
下次学习vector迭代器失效的实现过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1667713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker学习(带图详细)

一、安装docker 参考官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 查看系统版本 [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# [rootlocalhost ~]# uname -a Linux localhost.localdomai…

STM32平衡车-MPU6050的DMP库移植

本文目录 一、硬件接线二、需要移植的三个文件夹1. DMP文件夹目录2. IIC文件夹目录3. MPU6050文件夹目录 三、文件内容IO12C.cIO12C.hMPU6050.cMPU6050.hmain.c 四、附录1.更改IIC引脚 一、硬件接线 SCL-- PA11 SDA-- PA12 VCC-- 3.3v GND-- GND INT-- PC9 二、需要移植的三个…

[Kubernetes] Istio on Kubernetes 实践

文章目录 1.Kubernetes 创建2.Istio 部署2.1 下载 Istio2.2 安装 Istio 3.Istio on Kubernetes 实践3.1 部署 Bookinfo 示例应用3.2 确定入站 IP 和端口 1.Kubernetes 创建 主机名内部ip外部ipmaster192.168.66.2139.198.36.40node1192.168.66.3139.198.1.192node2192.168.66.…

数据结构——栈与队列的专题

文章目录 前言一、用队列实现栈二、用栈实现队列三、设计循环队列 前言 本篇是围绕栈与队列来展开&#xff0c;需要知道一定有关它们的相关基础知识 栈的详解 队列的详解 还有一道基础的栈题——有效的括号 一、用队列实现栈 原题链接&#xff1a;用队列实现栈 解题思路&a…

YOLOv5‘YOLOv7涨点必备:改进无参注意力SimAM

论文题目:SimAM: A Simple, Parameter-Free Attention Module for Convolutional Neural Networks 论文地址:http://proceedings.mlr.press/v139/yang21o/yang21o.pdf 源代码:https://github.com/ZjjConan/Sim 1.摘要 本文提出一种概念简单且非常有效的注意力模块。不同于…

攻防世界-web-file_include

题目 解题 通过阅读php代码&#xff0c;我们明显的可以发现&#xff0c;这个一个文件包含的类型题 文件包含漏洞也是一种“注入型漏洞”&#xff0c;其本质就是输入一段用户能够控制的脚本或者代码&#xff0c;并让服务器端执行。 require()&#xff0c;找不到被包含的文件时…

算法提高之单词接龙

算法提高之单词接龙 核心思想&#xff1a;dfs 预处理每两个字符串之间最短的公共部分长度 求最短公共 最终字符串是最长 dfs所有开头字符串 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 25;int g[N][N…

6818Linux内核开发移植

Linux内核开发移植 Linux内核版本变迁及其获得 Linux是最受欢迎的自由电脑操作系统内核&#xff0c; 是一个用C语言写成&#xff0c; 并且符合POSIX标准的类Unix操作系统 Linux是由芬兰黑客Linus Torvalds开发的&#xff0c; 目的是尝试在英特尔x86架构上提供自由免费的类Un…

nowcoder——回文结构

链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 我们来分析该题&#xff1a;我们首先要清楚什么是回文结构&#xff1f;其实就是对称结构。如果一个链表呈对称结构就说明该链表具有回文结构。 下面给上一些例子&#xff1a; 那我们怎么判断该链表是否属于回文结构呢&#xf…

基于springboot的代驾管理系统的设计与实现

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

漫谈ApplicationContext和BeanFactory的区别

各位大佬光临寒舍&#xff0c;希望各位能赏脸给个三连&#xff0c;谢谢各位大佬了&#xff01;&#xff01;&#xff01; 目录 1.背景介绍 2.细述ApplicationContext和BeanFactory 3.总结 1.背景介绍 当我们使用SpringBoot创建项目的时候会看到一串代码&#xff1a…

123.Android 简单的定位和语音识别 免费高德定位 免费语音识别 不需要接入SDK 不需要导入任何的离线包

//免费的定位 高德定位 不需要接入高德SDk也可进行高德定位&#xff1a; //免费的语音识别 不需要接入任何的SDK 也不需要导入任何的离线语音包&#xff1a; //CSDN 小妞得意 //具体代码实现 私聊 //---------------------------------------------------------------END…

Ubuntu 使用nginx部署agular项目

我的front-end是用的webpack&#xff0c;就直接执行的npm run build打包。 完成之后就可以\target\classes\static找到 &#xff0c;直接把整个static上传到需要部署的地方就可以了。 当然这个打包output路径也是angular.json配置好了的 sudo apt update sudo apt install n…

设计模式之开放封闭原则

文章目录 定义理解 小结 定义 开闭原则规定软件中的对象、类、模块和函数对扩展应该是开放的&#xff0c;但对于修改是封闭的。这意味着应该用抽象定义结构&#xff0c;用具体实现扩展细节&#xff0c;以此确保软件系统开发和维护过程的可靠性。 理解 怎么理解这个呢&#x…

51-48 CVPR 2024 | Vlogger: make your dream a vlog 自编剧制作视频博客

24年1月&#xff0c;上海交大、上海人工智能实验室、中科院联合发布Vlogger&#xff1a;make your dream a vlog。该论文主要工作是生成超过5分钟的视频博客vlog。鉴于现有文本到视频T2V生成方法很难处理复杂的故事情节和多样化的场景&#xff0c;本文提出了一个名为Vlogger的通…

Photoshop 2022 for Mac/win:释放创意,打造专业级的图像编辑体验

在数字图像编辑的世界里&#xff0c;Adobe Photoshop 2022无疑是那颗璀璨的明星。这款专为Mac和Windows用户设计的图像处理软件&#xff0c;以其卓越的性能和丰富的功能&#xff0c;赢得了全球数百万创作者的青睐。 Photoshop 2022在继承前代版本强大功能的基础上&#xff0c;…

Unity图文混排EmojiText的使用方式和注意事项

​​​​​​​ 效果演示&#xff1a; 使用方式&#xff1a; 1、导入表情 2、设置图片格式 3、生成表情图集 4、创建/修改目标材质球 5、测试 修复换行问题 修复前&#xff1a; 修复后&#xff1a; 修复代码&#xff1a; 组件扩展 1、右键扩展 2、组件归类&#…

力扣题目:机器人能否返回原点

力扣题目&#xff1a;机器人能否返回原点 题目链接: 657.机器人能否返回原点 题目描述 代码思路 题目思路很简单&#xff0c;只要L数量等于R&#xff0c;U的数量等于D。 代码纯享版 class Solution {public boolean judgeCircle(String moves) {int LR 0, UD 0;for(int …

贝叶斯分类器详解

1 概率论知识 1.1 先验概率 先验概率是基于背景常识或者历史数据的统计得出的预判概率&#xff0c;一般只包含一个变量&#xff0c;例如P(A)&#xff0c;P(B)。 1.2 联合概率 联合概率指的是事件同时发生的概率&#xff0c;例如现在A,B两个事件同时发生的概率&#xff0c;记…