string類詳解(下)

文章目錄

    • 4. string類的模擬實現
      • 4.1 構造 + 析構
      • 4.2 c_str
      • 4.3 下標遍歷
      • 4.4 迭代器
      • 4.5 插入
      • 4.6 刪除
      • 4.7 查找
      • 4.8 賦值
      • 4.9 交換
      • 4.10 提取子串
      • 4.11 比較大小
      • 4.12 流插入 && 流提取
    • 5. 現代版寫法的String類
      • 5.1 完整代碼
    • 6. 寫時拷貝(了解)

4. string類的模擬實現

首先,我們先補充一下關于編碼的知識:

int main()
{char buff1[] = "abcd";char buff2[] = "比特";cout << sizeof(buff1) << endl;cout << sizeof(buff2) << endl;cout << buff1 << endl;cout << buff2 << endl;return 0;
}

編碼
不同的string


如果嚴格按照標準的話,我們應該要實現成 basic_string ,但是這樣難度太大,要考慮各種編碼的拷貝,所以我們就實現的稍微簡單一些,不要實現成模板了。

4.1 構造 + 析構

//string::string()
//{
//	_str = new char[1]{ '\0' };
//	_size = 0;
//	_capacity = 0;
//}string::string(const char* str):_size(strlen(str))
{_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);
}//s2(s1)
string::string(const string& s)
{_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;
}string::~string()
{delete[] _str;_str = nullptr;_size = _capacity = 0;
}

4.2 c_str

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

4.3 下標遍歷

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

4.4 迭代器

string::iterator string::begin()
{return _str;
}string::iterator string::end()
{return _str + _size;
}

iterator封裝的意義

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

4.5 插入

void string::reserve(size_t n)
{if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}
}void string::push_back(char ch)
{if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;
}//"hello"  "xxxxxxxxxxxxx"
void string::append(const char* str)
{size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;
}string& string::operator+=(char ch)
{push_back(ch);return *this;
}
string& string::operator+=(const char* str)
{append(str);return *this;
}

插入示意圖(1)

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

插入示意圖(2)

void string::insert(size_t pos, const char* str)
{assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;
}

4.6 刪除

刪除示意圖

const size_t string::npos = -1;void string::erase(size_t pos, size_t len)
{assert(pos < _size);//len 大于等于后面字符個數時,有多少刪多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}
}

4.7 查找

size_t string::find(char ch, size_t pos)
{for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}size_t string::find(const char* str, size_t pos)
{char* p = strstr(_str + pos, str);return p - _str;
}

4.8 賦值

賦值示意圖

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

4.9 交換

交換示意圖

//s1.swap(s3)
void string::swap(string& s)
{std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);
}

4.10 提取子串

提取子串示意圖

string string::substr(size_t pos, size_t len)
{//len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}
}

4.11 比較大小

bool string::operator<(const string& s) const
{return strcmp(_str, s._str) < 0;
}bool string::operator>(const string& s) const
{return !(*this <= s);
}bool string::operator<=(const string& s) const
{return *this < s || *this == s;
}bool string::operator>=(const string& s) const
{return !(*this < s);
}bool string::operator==(const string& s) const
{return strcmp(_str, s._str) == 0;
}bool string::operator!=(const string& s) const
{return !(*this == s);
}

4.12 流插入 && 流提取

void string::clear()
{_str[0] = '\0';_size = 0;
}//一個字符一個字符放入str里,會有很多次擴容,可以優化
//istream& operator>> (istream& is, string& str)
//{
//	str.clear();//	//流提取(>>)提取不了空格和換行,istream里的函數get()可以
//	char ch = is.get();
//	while (ch != ' ' && ch != '\n')
//	{
//		str += ch;
//		ch = is.get();
//	}//	return is;
//}istream& operator>> (istream& is, string& str)
{str.clear();char buff[128];int i = 0;char ch = is.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;// 0 - 126if (i == 127){buff[i] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;
}ostream& operator<< (ostream& os, const string& str)
{for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;
}

5. 現代版寫法的String類

我們之前寫的拷貝構造和賦值運算符重載是傳統寫法,其實還有現代寫法:
拷貝構造現代寫法

//現代寫法(讓別人干活,交換)
//s2(s1)
string::string(const string& s)
{string tmp(s._str);/*std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);*///這個是我們寫的string類里的交換函數swap(tmp);
}

賦值運算符重載的現代寫法

/*string& string::operator=(const string& s)
{if (this != &s){string tmp(s._str);swap(tmp);}return *this;
}*///s1 = s3
string& string::operator=(string tmp)
{swap(tmp);return *this;
}

5.1 完整代碼

//string.h#include <iostream>
#include <assert.h>
using namespace std;namespace bit
{class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin();iterator end();const_iterator begin() const;const_iterator end() const;//string();string(const char* str = "");string(const string& s);//string& operator=(const string& s);string& operator=(string tmp);~string();const char* c_str() const;size_t size() const;char& operator[](size_t pos);const char& operator[](size_t pos) const;void reserve(size_t n);void push_back(char ch);void append(const char* str);string& operator+=(char ch);string& operator+=(const char* str);void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void erase(size_t pos = 0, size_t len = npos);size_t find(char ch, size_t pos = 0);size_t find(const char* str, size_t pos =  0);void swap(string& s);string substr(size_t pos = 0, size_t len = npos);bool operator<(const string& s) const;bool operator>(const string& s) const;bool operator<=(const string& s) const;bool operator>=(const string& s) const;bool operator==(const string& s) const;bool operator!=(const string& s) const;void clear();private://char _buff[16];char* _str = nullptr;size_t _size = 0;size_t _capacity = 0;const static size_t npos;//特例,const靜態成員變量只有整型可以這樣聲明定義(了解即可,不建議這樣寫)//const static size_t npos = -1;//不支持//const static double N = 2.2;};istream& operator>> (istream& is, string& str);ostream& operator<< (ostream& os, const string& str);
}
//string.cpp#include "string.h"namespace bit
{const size_t string::npos = -1;//string::string()//{//	_str = new char[1]{ '\0' };//	_size = 0;//	_capacity = 0;//}string::iterator string::begin(){return _str;}string::iterator string::end(){return _str + _size;}string::const_iterator string::begin() const{return _str;}string::const_iterator string::end() const{return _str + _size;}string::string(const char* str):_size(strlen(str)){_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);}//傳統寫法(實在人)//s2(s1)/*string::string(const string& s){_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}*///現代寫法(讓別人干活,交換)//s2(s1)string::string(const string& s){string tmp(s._str);/*std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);*///這個是我們寫的string類里的交換函數swap(tmp);}//s1 = s3//s1 = s1/*string& string::operator=(const string& s){if (this != &s){char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}*//*string& string::operator=(const string& s){if (this != &s){string tmp(s._str);swap(tmp);}return *this;}*///s1 = s3string& string::operator=(string tmp){swap(tmp);return *this;}string::~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}const char* string::c_str() const{return _str;}size_t string::size() const{return _size;}char& string::operator[](size_t pos){assert(pos < _size);return _str[pos];}const char& string::operator[](size_t pos) const{assert(pos < _size);return _str[pos];}void string::reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void string::push_back(char ch){/*if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);}//"hello"  "xxxxxxxxxxxxx"void string::append(const char* str){/*size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;*/insert(_size, str);}string& string::operator+=(char ch){push_back(ch);return *this;}string& string::operator+=(const char* str){append(str);return *this;}void string::insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}/*int end = _size;while (end >= (int)pos){_str[end + 1] = _str[end];--end;}*/size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;}void string::insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}/*int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];--end;}*/size_t end = _size + len;while (end > pos + len - 1){_str[end] = _str[end - len];--end;}memcpy(_str + pos, str, len);_size += len;}void string::erase(size_t pos, size_t len){assert(pos < _size);//len 大于等于后面字符個數時,有多少刪多少if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}}size_t string::find(char ch, size_t pos){for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}size_t string::find(const char* str, size_t pos){char* p = strstr(_str + pos, str);return p - _str;}//s1.swap(s3)void string::swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}string string::substr(size_t pos, size_t len){//len大于后面剩余字符,有多少取多少if (len > _size - pos){string sub(_str + pos);return sub;}else{string sub;sub.reserve(len);for (size_t i = 0; i < len; i++){sub += _str[pos + i];}return sub;}}bool string::operator<(const string& s) const{return strcmp(_str, s._str) < 0;}bool string::operator>(const string& s) const{return !(*this <= s);}bool string::operator<=(const string& s) const{return *this < s || *this == s;}bool string::operator>=(const string& s) const{return !(*this < s);}bool string::operator==(const string& s) const{return strcmp(_str, s._str) == 0;}bool string::operator!=(const string& s) const{return !(*this == s);}void string::clear(){_str[0] = '\0';_size = 0;}//一個字符一個字符放入str里,會有很多次擴容,可以優化//istream& operator>> (istream& is, string& str)//{//	str.clear();//	//流提取(>>)提取不了空格和換行,istream里的函數get()可以//	char ch = is.get();//	while (ch != ' ' && ch != '\n')//	{//		str += ch;//		ch = is.get();//	}//	return is;//}istream& operator>> (istream& is, string& str){str.clear();char buff[128];int i = 0;char ch = is.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;// 0 - 126if (i == 127){buff[i] = '\0';str += buff;i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;}ostream& operator<< (ostream& os, const string& str){for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;}
}
//Test.cpp#include "string.h"namespace bit
{void test_string1(){string s1("hello world");cout << s1.c_str() << endl;for (size_t i = 0; i < s1.size(); i++){s1[i]++;}for (size_t i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;//封裝:統一屏蔽了底層實現細節,提供了一種簡單通用的訪問容器的方式string::iterator it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;for (auto e : s1){cout << e << " ";}cout << endl;string s2;cout << s2.c_str() << endl;const string s3("xxxxxxx");string::const_iterator it3 = s3.begin();while (it3 != s3.end()){//*it3 = 'y';//errcout << *it3 << " ";++it3;}cout << endl;for (size_t i = 0; i < s3.size(); i++){//s3[i]++;cout << s3[i] << " ";}cout << endl;}void test_string2(){string s1("hello world");cout << s1.c_str() << endl;s1.push_back('x');cout << s1.c_str() << endl;s1.append("yyyyy");cout << s1.c_str() << endl;s1 += 'z';s1 += "mmmmmm";cout << s1.c_str() << endl;}void test_string3(){string s1("hello world");cout << s1.c_str() << endl;s1.insert(6, 'x');cout << s1.c_str() << endl;s1.insert(0, 'x');cout << s1.c_str() << endl;string s2("hello world");cout << s2.c_str() << endl;s2.insert(6, "yyy");cout << s2.c_str() << endl;s2.insert(0, "yyy");cout << s2.c_str() << endl;string s3("hello world");cout << s3.c_str() << endl;//s3.erase(6, 10);s3.erase(6);cout << s3.c_str() << endl;string s4("hello world");cout << s4.c_str() << endl;s4.erase(6, 3);cout << s4.c_str() << endl;}void test_string4(){string s1("hello world");cout << s1.find('o') << endl;cout << s1.find("wor") << endl;}void test_string5(){string s1("hello world");string s2(s1);s1[0] = 'x';cout << s1.c_str() << endl;cout << s2.c_str() << endl;string s3("yyyy");s1 = s3;cout << s1.c_str() << endl;cout << s3.c_str() << endl;string s4("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");s1 = s4;cout << s1.c_str() << endl;cout << s4.c_str() << endl;s1 = s1;cout << s1.c_str() << endl;cout << s3.c_str() << endl;std::swap(s1, s3);cout << s1.c_str() << endl;cout << s3.c_str() << endl;s1.swap(s3);cout << s1.c_str() << endl;cout << s3.c_str() << endl;}void test_string6(){string url("https://gitee.com/ailiangshilove/cpp-class/blob/master/%E8%AF%BE%E4%BB%B6%E4%BB%A3%E7%A0%81/C++%E8%AF%BE%E4%BB%B6V6/string%E7%9A%84%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95%E5%8F%8A%E4%BD%BF%E7%94%A8/TestString.cpp");size_t pos1 = url.find(':');string url1 = url.substr(0, pos1 - 0);cout << url1.c_str() << endl;size_t pos2 = url.find('/', pos1 + 3);string url2 = url.substr(pos1 + 3, pos2 - (pos1 + 3));cout << url2.c_str() << endl;string url3 = url.substr(pos2 + 1);cout << url3.c_str() << endl;}void test_string7(){//string s1("hello world");//cout << s1 << endl;string s1;cin >> s1;cout << s1 << endl;}void test_string8(){string s1("hello world");string s2(s1);cout << s1 << endl;cout << s2 << endl;string s3("xxxxxxxxxxxxxxxxxxxxxxxxx");s1 = s3;cout << s1 << endl;cout << s3 << endl;}
}int main()
{bit::test_string8();return 0;
}

6. 寫時拷貝(了解)

寫時拷貝就是一種拖延癥,是在淺拷貝的基礎之上增加了引用計數的方式來實現的。

引用計數:用來記錄資源使用者的個數。在構造時,將資源的計數給成1,每增加一個對象使用該資源,就給計數增加1,當某個對象被銷毀時,先給該計數減1,然后再檢查是否需要釋放資源,如果計數為1,說明該對象時資源的最后一個使用者,將該資源釋放;否則就不能釋放,因為還有其他對象在使用該資源。
寫時拷貝
舉個例子:

void copy_on_write()
{//如果計數不等于1,再去做深拷貝
}void string::push_back(char ch)
{//寫時拷貝copy_on_write();/*if (_size == _capacity){size_t newcapacity = 0 == _capacity ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;_str[_size + 1] = '\0';++_size;*/insert(_size, ch);
}

可以用下面的代碼來看是否是用了寫時拷貝:

void test_string9()
{std::string s1("hello world");std::string s2(s1);cout << (void*)s1.c_str() << endl;cout << (void*)s2.c_str() << endl;
}

Windows的VS下沒有用寫時拷貝,而Linux的g++就使用了寫時拷貝。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/71944.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/71944.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/71944.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

win11本地部署deepseek大模型(安裝ollama+docker+open-webui)最終實現自己的項目可通過API調用投喂數據后的模型

硬件配置&#xff1a;筆記本win11&#xff0c;內存32G&#xff0c;CPU銳龍7 &#xff0c;無獨顯&#xff1b;只能考慮deepseek-r1:1.5b模型。 第一步&#xff1a;安裝Ollama 此處不過多累贅了&#xff0c;https://ollama.com/官網選擇對應的系統版本下載即可。 需要注意的是…

WebSocket簡單介紹 并接入deepseek

目錄 什么是 WebSocket&#xff1f;工作原理&#xff1a; 為什么需要 WebSocket&#xff1f;WebSocket 的優勢HTTP 和 WebSocket 的區別WebSocket 的劣勢WebSocket 的應用場景WebSocket 握手過程1. 客戶端發起握手請求2. 服務器響應握手請求3. 建立連接 WebSocket 事件處理WebS…

虛擬機安裝教程

一、軟件下載與安裝 運行安裝程序: 雙擊下載的.exe文件&#xff0c;運行安裝程序。 按照安裝向導的提示進行操作。 通常情況下&#xff0c;你需要接受許可協議&#xff0c;選擇安裝目錄&#xff08;建議使用默認路徑&#xff0c;除非你有特殊需求&#xff09;&#xff0c;并選…

order by布爾盲注、時間盲注

pdo防御下&#xff0c;order by、limit不能參數綁定&#xff0c;可以進行sql注入 案例&#xff1a;靶場的less-46 布爾盲注&#xff1a; import requests from lxml import htmldef get_id_one(URL, paload):res requests.get(urlURL, paramspaload)tree html.fromstring(…

springboot集成deepseek4j

1、文檔地址 快速開始 - 零基礎入門Java AI 免費的模型 Models 2、pom文件依賴 parent依賴 <dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.12.0</version></dependency>&…

Visual Studio Code 跨平臺安裝與配置指南(附官方下載鏈接)

一、軟件定位與核心功能 Visual Studio Code&#xff08;簡稱VS Code&#xff09;是微軟開發的開源跨平臺代碼編輯器&#xff0c;支持超過50種編程語言的智能補全、調試和版本控制功能。2025版本新增AI輔助編程模塊&#xff0c;可自動生成單元測試代碼和API文檔注釋。 二、下載…

elementplus點擊按鈕直接預覽圖片

引用&#xff1a;https://blog.csdn.net/this_zq/article/details/134535539 <el-image-viewerv-if"showImagePreview":zoom-rate"1.2"close"closePreview":url-list"imgPreviewList"/>const showImagePreview ref(false) cons…

grafana K6壓測

文章目錄 install and runscript.jsoptions最佳實踐 report 解析 https://grafana.com/docs/k6/latest/get-started install and run install # mac brew install k6當前目錄下生成壓測腳本 # create file script.js k6 new [filename] # create file ‘script.js’ in …

解決IDEA使用Ctrl + / 注釋不規范問題

問題描述&#xff1a; ctrl/ 時&#xff0c;注釋縮進和代碼規范不一致問題 解決方式 設置->編輯器->代碼樣式->java->代碼生成->注釋代碼

項目實踐 之 pdf簡歷的解析和填充(若依+vue3)

文章目錄 環境背景最終效果前端講解左側模塊解析右側上傳模塊解析前端步驟 后端講解代碼前端 環境背景 若依前后端分離框架 vue最后邊附有代碼哦 最終效果 前端講解 左側模塊解析 1、左側表單使用el-form 注意&#xff1a; 1、prop出現的字段&#xff0c;需要保證是該類所…

【Electron入門】進程環境和隔離

目錄 一、主進程和渲染進程 1、主進程&#xff08;main&#xff09; 2、渲染進程&#xff08;renderer&#xff09; 二、預加載腳本 三、沙盒化 為單個進程禁用沙盒 全局啟用沙盒 四、環境訪問權限控制&#xff1a;contextIsolation和nodeIntegration 1、contextIsola…

如何看待 Kaiming He 最新提出的 Fractal Generative Models ?

何愷明團隊提出的分形生成模型(Fractal Generative Models) 引發了廣泛關注,其核心思想是通過遞歸調用生成模型模塊構建自相似結構,類似數學中的分形概念(如雪花結構),從而高效生成高分辨率數據(如圖像)。 Fractal Generative Models即分形生成模型,是一種新型的生成…

Debian系統終端輸入ifconfig報錯

報錯 bash: ifconfig: command not found 原因 Debian 上默認不安裝 ifconfig 軟件包。這是因為 ifconfig 已被棄用&#xff0c;取而代之的是新的 ip 命令。該 ip 命令現在負責修改或顯示路由、網絡設備、接口和隧道 如果仍然想使用舊的 ifconfig 命令&#xff0c;則必須顯式…

【NLP 27、文本分類任務 —— 傳統機器學習算法】

不要抓著枯葉哭泣&#xff0c;你要等待初春的新芽 —— 25.1.23 一、文本分類任務 定義&#xff1a;預先設定好一個文本類別集合&#xff0c;對于一篇文本&#xff0c;預測其所屬的類別 例如&#xff1a; 情感分析&#xff1a; 這家飯店太難吃了 —> 正類 …

Lumoz Chain正式上線:AI 時代的新算力破局者

新的敘事和技術突破永遠是推動行業前行的核心動力。當下&#xff0c;AI Agent無疑是最炙手可熱的賽道之一。 當加密世界將目光投向AI領域時&#xff0c;大多數項目仍停留在以AI為工具或應用場景的層面&#xff0c;試圖通過集成AI模型或優化鏈上功能來吸引用戶。然而&#xff0c…

Python - Python連接數據庫

Python的標準數據庫接口為&#xff1a;Python DB-API&#xff0c;Python DB-API為開發人員提供了數據庫應用編程接口。 PyMySQL 是在 Python3.x 版本中用于連接 MySQL 服務器的一個實現庫&#xff0c;Python2中則使用mysqldb。 PyMySQL 遵循 Python 數據庫 API v2.0 規范&…

面試八股文--數據庫基礎知識總結(1)

1、數據庫的定義 數據庫&#xff08;DataBase&#xff0c;DB&#xff09;簡單來說就是數據的集合數據庫管理系統&#xff08;Database Management System&#xff0c;DBMS&#xff09;是一種操縱和管理數據庫的大型軟件&#xff0c;通常用于建立、使用和維護數據庫。數據庫系統…

關于在java項目部署過程MySQL拒絕連接的分析和解決方法

前言 在最近一次部署項目一次項目部署過程中&#xff0c;由于沒有對MySQL數據庫的部分權限和遠程連接進行授權&#xff0c;導致了在執行項目功能API時&#xff0c;出現MySQL連接異常或MySQL拒絕連接的問題。 問題 以下是部分報錯截圖&#xff1a; 分析 根據日志提示&#xf…

PhotoLine綠色版 v25.00:全能型圖像處理軟件的深度解析

在圖像處理領域,PhotoLine以其強大的功能和緊湊的體積,贏得了國內外眾多用戶的喜愛。本文將為大家全面解析PhotoLine綠色版 v25.00的各項功能,幫助大家更好地了解這款全能型的圖像處理軟件。 一、迷你體積,強大功能 PhotoLine被譽為迷你版的Photoshop,其體積雖小,但功能卻…

阿里重磅模型深夜開源;DeepSeek宣布開源DeepGEMM;微軟開源多模態AI Agent基礎模型Magma...|網易數智日報

阿里重磅模型深夜開源&#xff1a;表現超越Sora、Pika&#xff0c;消費級顯卡就能跑 2月26日&#xff0c;25日深夜阿里云視頻生成大模型萬相2.1&#xff08;Wan&#xff09;正式宣布開源&#xff0c;此次開源采用Apache2.0協議&#xff0c;14B和1.3B兩個參數規格的全部推理代碼…