【c++】string模拟实现

string类的接口

namespace zjw
{class string{public:typedef char* iterator;typedef   const char* const_iterator;private:char* _str;int _size;int _capacity;};

这里的迭代器直接使用原生指针来封装。
_str为指向string数组的首地址的指针。
_size为string数组的大小。
_capacity为string数组的容量

基本函数

实现 函数返回string的首地址;
实现 函数返回string的尾地址;
实现 函数返回string的大小;
实现 函数返回string的容量;

	iterator begin(){return _str;}iterator end(){return _str+_size;}size_t size(){return _size;}size_t capacity(){return _capacity;}

如果一个string类不能被修改的话,就无法调用非const的成员函数
在这里插入图片描述

	const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}

默认构造以及析构函数

	string(const char* str = ""):_size(strlen(str)){_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}~string(){ delete[]_str;_str = nullptr;_size = _capacity = 0;}

这里有一个问题,就是默认构造传的缺省参数可以是nullptr 吗??
答案是不行的,因为strlen要将str解引用找’\0’,如果传nullptr的话,对空指针解引用就会出错。
这里也不可以传单字符‘\0’,因为这里的str是const char* 类型,而’\0’是char 类型


运算符重载下标访问函数

	char& operator[](size_t pos){assert(pos<_size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}

下标为_size的地方存的是’\0’,所以不用访问,pos<_size,为了让const迭代器不修改对于下标的值,修改上面得到下面,对上面进行函数重载

reserve函数

	void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[]_str;_str = tmp;_capacity = n;}}

在这里插入图片描述
注意:这里多开一个是为了存’\0’;

push_back()函数

	void push_back(char ch){if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';}

原来下标是_size的地方是‘\0’,然后之间在_size的地方放入ch,_size++,染后在补一个’\0’;要插入数据的一半都要扩容

append函数

	void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;//_str[_size] = '\0';}

尾插一个字符串,如果string的大小+要插入的字符串大小>_capacity,就扩容到_size + len,刚好,strcpy会从str开始直到遇到‘\0’一个字节一个字节拷贝到_str + _size(原字符串’\0’的地方),这里会把str字符串后面的‘\0’也拷贝过来。

运算符重载+=字符以及+=字符串

	string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}

在这里传引用返回是因为_str指向的空间是在堆上开的,出函数不会被销毁,所以可以传引用返回

insert函数(插入字符)

void insert(size_t pos, char ch){assert(pos<=_size);if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}size_t end = _size;while (end >=pos){_str[end+1] = _str[end];end--;}_str[pos] = ch;_size++;}

上面这个写法可以吗??
是不可以的
在这里插入图片描述
怎么修改呢??

	void insert(size_t pos, char ch){assert(pos<=_size);if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}size_t end = _size+1;while (end >pos){_str[end] = _str[end-1];end--;}_str[pos] = ch;_size++;}

这样就可以了,我们从’\0’的下一个位置开始end,此时end结束的条件是=0,所以不会陷入循环,这里和顺序表的insert很像,可以参考顺序表那里。


earse函数

	void earse(size_t pos, size_t len = npos){assert(pos < _size);if (len == npos || pos > _size-len){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}

删除从pos位置开始的len个字符长度的字符,如果len大于剩下的字符,就全删了,这里给的缺省值为npos=-1,可以认为是很大的数,绝对超过了pos后面的字符数,我们要在string里面声明一个npos,在类外面定义初始化。
在这里插入图片描述

如果len==npos或者len+pos>_size,就始要将pos开始后面的字符串全删除,我们直接在pos位置放’\0’即可,
_size=pos;
如果没有超过字符串
在这里插入图片描述


insert(插入字符串)

void insert(size_t pos, const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];end--;}strncpy(_str + pos, str, len);_size += len;}

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9d88ba8502954c0dbd884890654c612a.png

void test6(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.insert(2, "hello");cout << str.c_str();}

swap

	void swap(string& str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}
	void test12(){   string str1;string str2;str1 += "hello";str2+="nihao";cout << "str1:"<<str1 << endl;cout << "str2:"<<str2 << endl;str1.swap(str2);cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;}

在这里插入图片描述


这里我们自己实现的swap是类成员函数,但是#include< algorithm >这个头文件库里面也有一个swap,swap全局也有一个非成员函数swap

在这里插入图片描述

我们可以发现算法库中的swap需要完成三次的拷贝,以及一次析构(临时变量c的析构),而string里面定义一个全局的swap,就是为了防止调用算法库里面的swap,因为会先在全局找,然后会在展开的库里找,而全局的swap实现只需要调用类里面的swap即可

	void swap(string& x, string& y){x.swap(y);cout << "没使用库里的" << endl;}
	void test13(){string str1;string str2;str1 += "hello";str2 += "nihao";cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;swap(str1, str2);//检测是调用库里的,还是全局的cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;}

在这里插入图片描述

赋值以及拷贝构造

	string(const string& s){string tmp(s._str);swap(tmp);}string& operator=(string tmp){swap(tmp);return *this;}

根据调试发现
在这里插入图片描述

老版本赋值

		string& operator=(const string& s){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}

find函数(查找字符)

	size_t find(char ch, size_t pos = 0){for (int i = pos; i < _size; i++){if (_str[i] == ch)return i;}return npos;}

从pos位置开始查找,如果pos使用缺省,则从第一个位置开始查找,从pos位置开始遍历,如果找到返回下标,如果找不到返回npos

	void test7(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.insert(2, "hello");cout << endl;int ret = str.find('b', 0);cout << ret;}

在这里插入图片描述


find函数(查找子串)

		size_t find(const char* sub, size_t pos = 0) const{assert(pos < _size);//下标为_size的是‘\0’const char* ptr = strstr(_str + pos, sub);if (ptr != nullptr)//找到了,但是strstr返回的是找到子串的起始地址-字符串起始地址就是子串相对起始位置的长度{return ptr - _str;}else{return npos;}}
	void test8(){string str;str += "beijing huanyingni zhangjiawang";int ret = str.find("zhangjiawang");cout << ret;}

在这里插入图片描述


substr函数

string substr(size_t pos = 0, size_t len = npos) const{string substr;if (pos > _size - len){for (int i = pos; i <= _size; i++){substr += _str[i];}}else{for (int i = pos; i < pos + len; i++){substr += _str[i];}substr += '\0';}return substr;}

从pos位置开始取,取len个长度,分两种情况,如果从pos开始还没取到len长,就结束,就取到结尾,遍历pos到_size,string substr 保存遍历的值.
第二种,遍历pos到pos+len,string substr 保存遍历的值.最后记得加‘\0’;
在这里插入图片描述

运算符重载比较函数

	bool operator==(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str())==0;}bool operator>(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str());}bool operator<(const string& s1, const string& s2){return  !(s1 > s2 && s1 == s2);}bool operator<=(const string& s1, const string& s2){return  !(s1 > s2);}bool operator>=(const string& s1, const string& s2){return  !(s1 < s2);}bool operator!=(const string& s1, const string& s2){return  !(s1 == s2);}

注意这里为什么要搞成全局的呢??

	void test10(){string str1;string str2;str1 += "abc";str2 += "aba";cout << (str1 == str2) << endl;cout << ("aba" == str2) << endl;//2cout << (str2== "aba") << endl;}

因为第二种的话不满足类成员做左操作数,全局的话就可以,而第三个是会搞一个类型转换.

	void test10(){string str1;string str2;str1 += "abc";str2 += "aba";cout << (str1 == str2) << endl;cout << ("aba" == str2) << endl;cout << (str2== "aba") << endl;cout << (str1>str2) << endl;cout << (str1 >=str2) << endl;cout << (str1<str2) << endl;cout << (str1 <=str2) << endl;cout << (str1!=str2) << endl;}

在这里插入图片描述


运算符重载流插入

	ostream& operator<<(ostream& out, const string& s){for (auto e : s)//遍历一个一个输出{out << e;}return out;}

有返回值是为了可以连续流插入

运算符重载流提取

版本一:

	istream& operator>>(istream& in, string& s){char ch;in >> ch;//读取字符到chwhile (ch != ' ' && ch != '\n')//读到‘ ’或‘\n’结束输入{s += ch;//将ch加进去in >> ch;//循环读取}return in;}

这样写会有一个问题,就是cin和scanf一样默认‘\n’和‘ ’是分割符不会进行读取,所以ch不会是空格或换行,所以陷入死循环.
在这里插入图片描述
版本2:
c语言中可以用getchar来读取,而c++中存在get就可以读空格

istream& operator>>(istream& in, string& s){char ch;in.get(ch);while (ch != ' ' && ch != '\n'){s += ch;in.get(ch);}return in;}
	void test11(){string str1;string str2;cin >> str1;//>>str2;//>>str2;cout << str1;//cout << str1.capacity();}

在这里插入图片描述


版本3
由于我们在s+=ch,会出现频繁扩容,影响效率,我们应该怎么解决呢??
我们可以提前开好空间,但是不知道应该开多大.假如说我们开128个

	istream& operator>>(istream& in, string& s){char ch;in.get(ch);s.reserve(128);while (ch != ' ' && ch != '\n'){s += ch;in.get(ch);}return in;}
	void test11(){string str1;string str2;cin >> str1;//>>str2;//>>str2;//cout << str1;cout << str1.capacity();}

在这里插入图片描述
两个数据开128就会有极大的浪费,多一点还好
在这里插入图片描述
版本4

	istream& operator>>(istream& in, string& s){s.clear();//可能我们s里面之前有数据,但是流提取是要覆盖的char ch;ch = in.get();char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';s += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;}

这里感觉可以类比冯诺依曼体系,buff就相当于内存,先将输入的值放在内存buff里面,等到装满了,在一次性给s,减少搬运次数.避免了一次空间开的很大,而数据只有几个
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

clear

	void clear(){_size = 0;_str[0] = '\0';}

c_str

将const string* 转化为const char*

	const char* c_str() const{return _str;}

cout不能直接处理自定义类型string,但是可以使用c_str将string转成常量字符串,内置类型就可以直接打印


源码

.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
#include<assert.h>
#include<iostream>
#include<algorithm>
namespace zjw
{class string{public:typedef char* iterator;typedef   const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""):_size(strlen(str)){_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}~string(){delete[]_str;_str = nullptr;_size = _capacity = 0;}size_t size(){return _size;}size_t capacity(){return _capacity;}char& operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[]_str;_str = tmp;_capacity = n;}}void push_back(char ch){if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';}void append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;//_str[_size] = '\0';}string& operator+=(char ch){push_back(ch);return *this;}string& operator+=(const char* str){append(str);return *this;}void insert(size_t pos, char ch){assert(pos <= _size);if (_capacity == _size){reserve(_capacity == 0 ? 4 : _capacity * 2);}size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;}const char* c_str() const{return _str;}void earse(size_t pos, size_t len = npos){assert(pos < _size);if (len == npos || pos > _size - len){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}bool empty(){return _size == 0;}void resize(size_t n, char ch = '\0'){if (n <= _size){_str[n] = '\0';_size = n;}else{reserve(n);for (size_t i = _size; i < n; i++){_str[i] = ch;}_size = n;}}void insert(size_t pos, const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];end--;}strncpy(_str + pos, str, len);_size += len;}size_t find(char ch, size_t pos = 0){for (int i = pos; i < _size; i++){if (_str[i] == ch)return i;}return npos;}size_t find(const char* sub, size_t pos = 0) const{assert(pos < _size);const char* ptr = strstr(_str + pos, sub);if (ptr != nullptr){return ptr - _str;}else{return npos;}}string substr(size_t pos = 0, size_t len = npos) const{string substr;if (pos > _size - len){for (int i = pos; i <= _size; i++){substr += _str[i];}}else{for (int i = pos; i < pos + len; i++){substr += _str[i];}substr += '\0';}return substr;}void swap(string& str){std::swap(_str, str._str);std::swap(_size, str._size);std::swap(_capacity, str._capacity);}string(const string& s){string tmp(s._str);swap(tmp);}string& operator=(string tmp){swap(tmp);return *this;}string& operator=(const string& s){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}void clear(){_size = 0;_str[0] = '\0';}friend istream& operator>>(istream& in, string& s);public:static const int  npos;private:char* _str;int _size;int _capacity;};const int string::npos = -1;void swap(string& x, string& y){x.swap(y);cout << "没使用库里的" << endl;}istream& operator>>(istream& in, string& s){s.clear();char ch;ch = in.get();char buff[128];int i = 0;while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == 127){buff[127] = '\0';s += buff;i = 0;}ch = in.get();}if (i > 0){buff[i] = '\0';s += buff;}return in;}//istream& operator>>(istream& in, string& s)//{//	//	char ch;//	//	in.get(ch);//	//	s.reserve(128);//	while (ch != ' ' && ch != '\n')//	{//	//	//		s += ch;//		in.get(ch);//	}//	//		//		//	//	return in;//}bool operator==(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str())==0;}bool operator>(const string& s1, const string& s2){return strcmp(s1.c_str(), s2.c_str());}bool operator<(const string& s1, const string& s2){return  !(s1 > s2 && s1 == s2);}bool operator<=(const string& s1, const string& s2){return  !(s1 > s2);}bool operator>=(const string& s1, const string& s2){return  !(s1 < s2);}bool operator!=(const string& s1, const string& s2){return  !(s1 == s2);}ostream& operator<<(ostream& out, const string& s){for (auto e : s){out << e;}return out;}//istream& operator>>(istream& in, string& s)//{//	s.clear();//	char ch;//	//	ch = in.get();//	//in >> ch;//	s.reserve(128);//	while (ch != ' ' && ch != '\n')//	{//		//		s += ch;//		ch = in.get();//		//in >> ch;//	}//	return in;//////////}void test1(){string str;str += 'a';str += 'b';str += "beijing";string::iterator it = str.begin();while (it != str.end()){cout << *it << " ";it++;}}void test2(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.push_back('a');str.push_back('a');string::iterator it = str.begin();while (it != str.end()){cout << *it << " ";it++;}cout << str[2];}void test3(){string str;str.append("stringbj");for (auto& e : str){cout << e << " ";}}void print_string(const string it){string::const_iterator res = it.begin();while (res != it.end()){cout << *res << " ";++res;}}void test4(){string str;str += "abc";str.append("stringbj");string::iterator it = str.begin();while (it != str.end()){cout << *it << " ";it++;}//str.insert(0, 'g');for (auto& e : str){cout << e << " ";}cout << endl;// str.earse(1,string::npos);*//* for (auto e : str){cout << e << " ";}*/// print_string(str);}void test5(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.resize(10);/* string::iterator it = str.begin();while (it != str.end()){cout << *it << " ";it++;}*/cout << str.c_str();}void test6(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.insert(2, "hello");cout << str.c_str();}void test7(){string str;str.push_back('a');str.push_back('a');str.push_back('b');str.insert(2, "hello");cout << endl;int ret = str.find('b', 0);cout << ret;}void test8(){string str;str += "beijing huanyingni zhangjiawang";int ret = str.find("zhangjiawang");cout << ret;}void test9(){string str;str += "beijing huanyingni zhangjiawang";string op = str.substr(0, 10);cout << op.c_str();}void test10(){string str1;string str2;str1 += "abc";str2 += "aba";cout << (str1 == str2) << endl;cout << ("aba" == str2) << endl;cout << (str2== "aba") << endl;cout << (str1>str2) << endl;cout << (str1 >=str2) << endl;cout << (str1<str2) << endl;cout << (str1 <=str2) << endl;cout << (str1!=str2) << endl;}void test11(){string str1;string str2;cin >> str1;//>>str2;//>>str2;//cout << str1;cout << str1.capacity();}void test12(){   string str1;string str2;str1 += "hello";str2+="nihao";cout << "str1:"<<str1 << endl;cout << "str2:"<<str2 << endl;str1.swap(str2);cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;}void test13(){string str1;string str2;str1 += "hello";str2 += "nihao";cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;swap(str1, str2);cout << "str1:" << str1 << endl;cout << "str2:" << str2 << endl;}void test14(){string str2;str2 += "nihao";string str1(str2);}}

.cpp

#include"标头.h"int main()
{zjw::test11();
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FPGA的时钟资源

目录 简介 Clock Region详解 MRCC和SRCC的区别 BUFGs 时钟资源总结 简介 7系列FPGA的时钟结构图&#xff1a; Clock Region&#xff1a;时钟区域&#xff0c;下图中有6个时钟区域&#xff0c;用不同的颜色加以区分出来 Clock Backbone&#xff1a;从名字也能看出来&#x…

Unity3d调用C++ dll中的函数

一、生成dll 1.新建dll工程 2. 不用管dllmain.cpp&#xff0c;添加自定义Helper.h和Helper.cpp 3.添加要在外部调用的方法 //头文件 #define DLLEXPORT extern "C" __declspec(dllexport) DLLEXPORT int _stdcall Addition(int x, int y); DLLEXPORT int _stdcal…

基于qt的图书管理系统----05其他优化

参考b站&#xff1a;视频连接 源码github&#xff1a;github 目录 1 优化借阅记录显示2 时间显示为年月日3 注册接口 1 优化借阅记录显示 现在只能显示部分信息&#xff0c;把接的书名和人的信息全部显示 在sql语句里替换为这一句即可实现查询相关联的所有信息 QString str…

round四舍五入在python2与python3版本间区别

round()方法返回数值的小数点四舍五入到n个数字。 语法 以下是round()方法的语法&#xff1a; round( x ,n) 参数 x --这是一个数值&#xff0c;表示需要格式化的数值 n --这也是一个数值,表示小数点后保留多少位 返回值 该方法返回 数值x 的小数点四舍五入到n个数字 …

Rust教程:How to Rust-从开始之前到Hello World

本文为第0篇 专栏简介 本专栏是优质Rust技术专栏&#xff0c;推荐精通一门技术栈的蟹友&#xff0c;不建议基础的同学&#xff08;无基础学Rust也是牛人[手动捂脸]&#xff09; 感谢Rust圣经开源社区的同学&#xff0c;为后来者提供了非常优秀的Rust学习资源 本文使用&…

物联网电气融合实训室建设方案

1 教学实训总体设计 1.1 建设背景 &#xff08;一&#xff09;政策推动与战略部署 近年来&#xff0c;物联网技术在全球范围内得到了广泛的关注和应用。作为信息技术的重要组成部分&#xff0c;物联网在推动经济转型升级、提升社会管理水平、改善民生福祉等方面发挥着重要作…

面试宝典-【redis】

目录 1.什么是缓存穿透 ? 怎么解决 ? 2.什么是布隆过滤器 3.什么是缓存击穿 ? 怎么解决 ? 4.什么是缓存雪崩 ? 怎么解决 ? 5.redis做为缓存&#xff0c;mysql数据如何与redis进行同步?(双写) 6.排他锁是如何保证读写、读读互斥的呢&#xff1f; 7.你听说过延…

【论文阅读】(2024.03.05-2024.03.15)论文阅读简单记录和汇总

(2024.03.05-2024.03.15)论文阅读简单记录和汇总 2024/03/05&#xff1a;随便简单写写&#xff0c;以后不会把太详细的记录在CSDN&#xff0c;有道的Markdown又感觉不好用。 目录 &#xff08;ICMM 2024&#xff09;Quality Scalable Video Coding Based on Neural Represent…

Linux之线程概念

目录 一、细粒度划分 1、堆区细粒度划分 2、物理内存和可执行程序细粒度划分 3、虚拟地址到物理地址的转化 二、线程的概念 1、基本概念 2、线程的优点 3、线程的缺点 4、线程异常 5、线程用途 三、Linux下的进程和线程 一、细粒度划分 1、堆区细粒度划分 在语言…

OS-Copilot:实现具有自我完善能力的通用计算机智能体

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ AI 缩小了人类间的知识和技术差距 论文标题&#xff1a;OS-Copilot: Towards Generalist Computer Agents with Self-Improvement 论文链接&#xff1a;https://arxiv.org/abs/2402.07456 项目主页&a…

目标网站屏蔽右键检查(使用开发者工具)

问题&#xff1a; 通过网络触手中想要获取某网站的数据出现&#xff1a;鼠标右击&#xff0c;或按ctrl F10 键 无反应&#xff08;也就是打不开类似谷歌的开发工具&#xff09; 问题同等与&#xff1a; 解决网页屏蔽F12或右键打开审查元素 引用&#xff1a; 作者&#xff…

学会玩游戏,智能究竟从何而来?

最近在读梅拉妮米歇尔《AI 3.0》第三部分第九章&#xff0c;谈到学会玩游戏&#xff0c;智能究竟从何而来&#xff1f; 作者: [美] 梅拉妮米歇尔 出版社: 四川科学技术出版社湛庐 原作名: Artificial Intelligence: A Guide for Thinking Humans 译者: 王飞跃 / 李玉珂 / 王晓…

基于jsp+mysql+Spring+mybatis的SSM汽车保险理赔管理系统设计和实现

基于jspmysqlSpringmybatis的SSM汽车保险理赔管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

图片在div完全显示

效果图&#xff1a; html代码&#xff1a; <div class"container" style" display: flex;width: 550px;height: 180px;"><div class"box" style" color: red; background-color:blue; width: 50%;"></div><div …

服务器与文件内数据的 LENGTH_IN_CHAR 参数不匹配

导入数据库数据的时候出现这个 怎么解决&#xff1a;重建数据库实例 下面是达梦的工具 使用DM数据库配置助手 新建、删除实例 新建实例时的配置需要注意的选项 主要是字符集、大小写、和VARCHAR类型以字符为单位 出现【LENGTH_IN_CHAR 参数不匹配】勾选【VARCHAR类型以字…

JVM运行时数据区——对象的实例化内存布局与访问定位

文章目录 1、对象的实例化1.1、创建对象的方式1.2、创建对象的步骤 2、对象的内存布局3、对象的访问定位3.1、对象访问的定位方式3.2、使用句柄访问3.3、使用指针访问 4、小结 平时大家经常使用new关键字来创建对象&#xff0c;那么我们创建对象的时候&#xff0c;怎么去和运行…

【R语言爬虫实战】抓取省市级城市常务会议内容

&#x1f349;CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一&#xff5c;统计学&#xff5c;干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项&#xff0c;参与研究经费10w、40w级横向 文…

在vue3中使用el-tree-select做一个树形下拉选择器

el-tree-select是一个含有下拉菜单的树形选择器&#xff0c;结合了 el-tree 和 el-select 两个组件的功能。 因为包含了el-tree的功能&#xff0c;我们可以自定义tree的节点&#xff0c;创造出想要的组件 使用default插槽可以自定义节点内容&#xff0c;它的default插槽相当于…

基于美洲狮优化算法(Puma Optimizar Algorithm ,POA)的无人机三维路径规划(提供MATLAB代码)

一、无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径&#xff0c;使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一&#xff0c;它可以通过算法和模型来确定无人机的航迹&#xff0c;以避开障碍物、优化飞行…

STM32之串口中断接收UART_Start_Receive_IT

网上搜索了好多&#xff0c;都是说主函数增加UART_Receive_IT()函数来着&#xff0c;实际正确的是UART_Start_Receive_IT()函数。 —————————————————— 参考时间&#xff1a;2024年3月9日 Cube版本&#xff1a;STM32CubeMX 6.8.1版本 参考芯片&#xff1a…