C++string类(个人笔记)

string类

    • 1.认识string的接口以及熟练使用常用接口
      • 1.1string类对象的常见构造
      • 1.2string类对象的容量操作
      • 1.3string类对象的访问及遍历操作
      • 1.4string类对象的修改操作
    • 2.vs 和g++下string结构的说明
    • 3.string类运用的笔试题
    • 4.string类的模拟实现


1.认识string的接口以及熟练使用常用接口

1.1string类对象的常见构造

constructor函数名称功能说明
string() (重点)构造空的string类对象,即空字符串
string(const char* s) (重点)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s) (重点)拷贝构造函数

演示:

void Teststring()
{
 	string s1; // 构造空的string类对象s1
 	string s2("hello bit"); // 用C格式字符串构造string类对象s2
 	string s3(s2); // 拷贝构造s3
}

1.2string类对象的容量操作

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity (重点)返回空间总大小
empty(重点)检测字符串释放为空串,是返回true,否则返回false
clear(重点)清空有效字符
reserve(重点)为字符串预留空间
resize(重点)将有效字符的个数该成n个,多出的空间用字符c填充

注意:

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(size_t n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

演示:

#include<iostream>
using namespace std;
#include<string>
//
//测试string容量相关的接口
//size/clear/resize
void Teststring1()
{
	//注意:string类对象支持直接用cin和cout进行输入和输出
	string s("helle,ljh !");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	//将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
	s.clear();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	//将s中有效字符个数增加到10个,多出位置yon‘a’进行填充
	//"aaaaaaaaaa"
	s.resize(10, 'a');
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	//将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
	//“aaaaaaaaaa\0\0\0\0\0”
	//注意此时s中有效字符个数已经增加到15个
	s.resize(15);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	//将s中的有效字符个数缩小到5个
	s.resize(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;
}
///
void Teststring2()
{
	string s;
	//测试reserve是否会改变string中有效元素个数
	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	//测试reserve参数小于string的底层空间大小时,是否会将空间缩小
	s.reserve(50);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

//
//利用reserve提高插入数组的效率,避免增容带来的开销
void TestPushBack()
{
	string s;
	size_t sz = s.capacity();
	cout << "making s grow:\n" << endl;
	for (int i = 0;i < 100;i++)
	{
		s.push_back('a');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed" << sz << endl;
		}
	}
}

//构建string时,如果提前已经知道string中大概要放多少个元素,可提前将string中空间设置好
void TestPushBackReserve()
{
	string s;
	s.reserve(100);
	size_t sz = s.capacity();

	cout << "making s grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		s.push_back('a');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}

1.3string类对象的访问及遍历操作

函数名称功能说明
operator[] (重点)返回pos位置的字符,const string类对象调用
begin+endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin+rendrend获取一个字符的迭代器 + rbegin获取最后一个字符下一个位置的迭代器
范围forC++11支持更简洁的范围for的新遍历方式

演示:

//string的遍历
//begin()+end() for+[] 范围for
//注意:string遍历时使用最多的还是for+下标或者范围for(C++11后才支持)
//begin()+end()大多数使用在需要使用STL提供的算法操作string时,比如:采用reverse逆置string
void Teststring3()
{
	string s1("hello ljh");
	const string s2("Hello ljh");
	cout << s1 << " " << s2 << endl;
	cout << s1[0] << " " << s2[0] << endl;

	s1[0] = 'H';
	cout << s1 << endl;
	//s2[0]='h';代码编译失败,因为const类型对象不能修改
}

void Teststring4()
{
	string s("hello ljh");
	//3种遍历方式:
	// 需要注意的以下三种方式除了遍历string对象,还可以遍历是修改string中的字符,
	// 另外以下三种方式对于string而言,第一种使用最多
	//1.for+operator[]
	for (size_t i = 0;i < s.size();i++)
	{
		cout << s[i] << endl;
	}
	//2.迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << endl;
		++it;
	}

	//string::reverse_iterator rit=s.rbegin();
	//C++11之后,直接使用auto定义迭代器,让编译器推到迭代器的类型
	auto rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << endl;
	}
	//范围for
	for (auto ch : s)
	{
		cout << ch << endl;
	}
}

1.4string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=(重点)在字符串后追加字符串str
c_str返回C格式字符串
find+npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

演示:

//测试string:
//1.插入(拼接)方式:push_back append aperator+=
//2.正向和反向查找:find()+rfind()
//3.截取字串:substr()
//4.删除:erase
void Teststring5()
{
	string str;
	str.push_back(' ');   // 在str后插入空格
	str.append("hello");  // 在str后追加一个字符"hello"
	str += 'b';           // 在str后追加一个字符'b'   
	str += "it";          // 在str后追加一个字符串"it"
	cout << str << endl;
	cout << str.c_str() << endl;   // 以C语言的方式打印字符串

	//获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');
	string suffix(file.substr(pos, file.size() - pos));
	cout << suffix << endl;

	// npos是string里面的一个静态成员变量
	// static const size_t npos = -1;

	//取出url中的域名
	string url("http://www.cplusplus.com/reference/string/string/find/");
	cout << url << endl;
	size_t start = url.find("://");
	if (start == string::npos)
	{
		cout << "invalid url" << endl;
		return;
	}
	start += 3;
	size_t finish = url.find('/', start);
	string address = url.substr(start, finish - start);
	cout << address << endl;
	// 删除url的协议前缀
	pos = url.find("://");
	url.erase(0, pos + 3);
	cout << url << endl;
}

2.vs 和g++下string结构的说明

注意:下面结构是在32位平台下进行验证,32位平台下指针占4个字节.

  1. vs下string结构
    string总共占28个字节,先是有一个联合体,联合体用来定义string中字符串的存储空间:
    当字符串长度小于16时,使用内部固定的字符数组来存放
    当字符串长度大于等于16时,从堆上开辟空间
union _Bxty
{ 	// storage for small buffer or pointer to larger one
 	value_type _Buf[_BUF_SIZE];
 	pointer _Ptr;
 	char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量
最后:还有一个指针做一些其他事情。
16+4+4+4=28字节
在这里插入图片描述

  1. g++下string的结构
    G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:
    空间总大小
    字符串有效长度
    引用计数
struct _Rep_base
{
 	size_type _M_length;
 	size_type _M_capacity;
 	_Atomic_word _M_refcount;
};

指向堆空间的指针,用来存储字符串。

3.string类运用的笔试题

仅反转字母
在这里插入图片描述

class Solution {
public:
    bool isLetter(char ch)
    {
        if('a'<=ch&&ch<='z')
        {
            return true;
        }
        if('A'<=ch&&ch<='Z')
        {
            return true;
        }
        return false;
    }

    void reverse(string& s)
    {
        size_t begin=0;
        size_t end=s.size()-1;
        while(begin<end)
        {
            if(isLetter(s[begin])&&isLetter(s[end]))
            {
                char temp=s[begin];
                s[begin]=s[end];
                s[end]=temp;
                begin++;
                end--;
            }
            else if (!isLetter(s[begin]))
            {
                begin++;
            }
            else if (!isLetter(s[end]))
            {
                end--;
            }
        }
    }


    string reverseOnlyLetters(string s)
    {
        if(s.empty())
        {
            return s;
        }
        reverse(s);
        return s;
    }
};

找字符串中第一个只出现一次的字符
在这里插入图片描述

class Solution {
public:
    int firstUniqChar(string s)
    {
        int count[256]={0};
        int size=s.size();
        for(int i=0;i<size;i++)
        {
            count[s[i]]++;
        }
        for(int i=0;i<size;i++)
        {
            if(count[s[i]]==1)
            {
                return i;
            }
        }
        return -1;
    }
};

字符串里面最后一个单词的长度
在这里插入图片描述

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

int main()
{
    string s;
    while(getline(cin,s))
    {
        size_t pos=s.rfind(' ');
        cout<<s.size()-pos-1<<endl;
    }
    return 0;
}

验证回文串
在这里插入图片描述

class Solution {
public:
    bool isLetterOrNumber(char ch)
    {
        if(('a'<=ch&&ch<='z')||('A'<=ch&&ch<='Z')||('0'<=ch&&ch<='9'))
        {
            return true;
        }
        return false;
    }

    bool isPalindrome(string s)
    {
        if(s.empty())
        {
            return true;
        }
        for(auto& ch:s)
        {
            if('a'<=ch&&ch<='z')
            {
                ch-=32;
            }
        }
        int begin=0;
        int end=s.size()-1;
        while(begin<end)
        {
            while(begin<end && !isLetterOrNumber(s[begin]))
            {
                begin++;
            }
            while(begin<end && !isLetterOrNumber(s[end]))
            {
                end--;
            }
            if(s[begin]!=s[end])
            {
                return false;
            }
            begin++;
            end--;
        }
        return true;
    }
};

字符串相加
在这里插入图片描述

class Solution {
public:
    string addStrings(string num1, string num2)
    {
        int end1=num1.size()-1;
        int end2=num2.size()-1;
        int value1=0;
        int value2=0;
        int next=0;
        string addret;
        while(end1>=0||end2>=0)
        {
            if(end1>=0)
            {
                value1=num1[end1--]-'0';
            }
            else
            {
                value1=0;
            }
            if(end2>=0)
            {
                value2=num2[end2--]-'0';
            }
            else
            {
                value2=0;
            }
            int valueret=value1+value2+next;
            if(valueret>9)
            {
                valueret-=10;
                next=1;
            }
            else
            {
                next=0;
            }
            addret+=(valueret+'0');
        }
        if(next==1)
        {
            addret+='1';
        }
        reverse(addret.begin(),addret.end());
        return addret;
    }
};

反转字符串||
在这里插入图片描述

class Solution {
public:
    string reverseStr(string s, int k)
    {
        int n=s.size();
        for(int i=0;i<n;i+=2*k)
        {
            reverse(s.begin()+i,s.begin()+min(i+k,n));
        }
        return s;
    }
};

反转字符串中的单词|||
在这里插入图片描述

class Solution {
public:
    string reverseWords(string s)
    {
        int size=s.size();
        int i=0;
        while(i<size)
        {
            int start=i;
            while(i<size&&s[i]!=' ')
            {
                i++;
            }
            int left=start;
            int right=i-1;
            while(left<right)
            {
                swap(s[left],s[right]);
                left++;
                right--;
            }
            while(i<size&&s[i]==' ')
            {
                i++;
            }
        }
        return s;
    }
};

反转字符串的单词|||
在这里插入图片描述

class Solution {
public:
    string reverseWords(string s)
    {
        int size = s.size();
        for (int i = 0; i < size;)
        {
            // 查找空格的位置
            size_t pos = s.find(' ', i);
            // 如果没有找到空格,则说明是最后一个单词
            if (pos == string::npos)
                pos = size;
            // 反转当前单词
            reverse(s.begin() + i, s.begin() + pos);
            // 更新 i,跳过空格
            i = pos + 1;
        }
        return s;
    }
};

字符串相乘
在这里插入图片描述

//竖式相乘法
class Solution {
public:
    string multiply(string num1, string num2)
    {
        int n1=num1.size();
        int n2=num2.size();
        string res(n1+n2,'0');
        for(int i=n2-1;i>=0;i--)
        {
            for(int j=n1-1;j>=0;j--)
            {
                int temp=(res[i+j+1]-'0')+(num1[j]-'0')*(num2[i]-'0');
                res[i+j+1]=temp%10+'0';//当前位
                res[i+j]+=temp/10; //前一位加上进位,res[i+j]已经初始化为'0',加上int类型自动转化为char,所以此处不加'0'
            }
        }
        //去除首位'0'
        for(int i=0;i<n1+n2;i++)
        {
            if(res[i]!='0')
                return res.substr(i);
        }
        return "0";
    }
};

找出字符串中第一个只出现一次的字符
在这里插入图片描述

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

int main()
{
    string s;
    cin>>s;
    int count[256]={0};
    for(int i=0;i<s.size();i++)
    {
        count[s[i]]++;
    }
    for(int i=0;i<s.size();i++)
    {
        if(count[s[i]]==1)
        {
            cout<<s[i];
            return 0;
        }
    }
    cout<<-1;
    return 0;
}

4.string类的模拟实现

#pragma once
#include<assert.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
namespace ljh
{
	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()
			:_str(new char[1]{'\0'})
			,_size(0)
			,_capacity(0)
		{}*/

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

		// 传统写法
		// s2(s1)
		//string(const string& s)
		//{
		//	_str = new char[s._capacity+1];
		//	strcpy(_str, s._str);
		//	_size = s._size;
		//	_capacity = s._capacity;
		//}


		 s2 = s3
		//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;
		//}

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

		// s2(s1)
		string(const string& s)
			:_str(nullptr)
			, _size(0)
			, _capacity(0)
		{
			string tmp(s._str);
			swap(tmp);
		}

		// s2 = s3
		//string& operator=(const string& s)
		//{
		//	if (this != &s)
		//	{
		//		string tmp(s);
		//		//this->swap(tmp);
		//		swap(tmp);
		//	}

		//	return *this;
		//}

		// s2 = s3
		string& operator=(string tmp)
		{
			swap(tmp);

			return *this;
		}

		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

		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_t capacity() const
		{
			return _capacity;
		}

		size_t size() const
		{
			return _size;
		}

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

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

				_capacity = n;
			}
		}

		void resize(size_t n, char ch = '\0')
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				reserve(n);
				while (_size < n)
				{
					_str[_size] = ch;
					++_size;
				}

				_str[_size] = '\0';
			}
		}

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

			return npos;
		}

		size_t find(const char* sub, size_t pos = 0)
		{
			const char* p = strstr(_str + pos, sub);
			if (p)
			{
				return p - _str;
			}
			else
			{
				return npos;
			}
		}

		string substr(size_t pos, size_t len = npos)
		{
			string s;
			size_t end = pos + len;
			if (len == npos || pos + len >= _size) // 有多少取多少
			{
				len = _size - pos;
				end = _size;
			}

			s.reserve(len);
			for (size_t i = pos; i < end; i++)
			{
				s += _str[i];
			}

			return s;
		}

		void push_back(char ch)
		{
			if (_size == _capacity)
			{
				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;
		}

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

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

		// insert(0, 'x')
		void insert(size_t pos, char ch)
		{
			assert(pos <= _size);
			if (_size == _capacity)
			{
				reserve(_capacity == 0 ? 4 : _capacity * 2);
			}

			// 17:17
			size_t end = _size + 1;
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				--end;
			}

			_str[pos] = ch;
			_size++;
		}

		void 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;
			}

			strncpy(_str + pos, str, len);
			_size += len;
		}

		void erase(size_t pos, size_t len = npos)
		{
			assert(pos < _size);

			if (len == npos || pos + len >= _size)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				size_t begin = pos + len;
				while (begin <= _size)
				{
					_str[begin - len] = _str[begin];
					++begin;
				}
				_size -= len;
			}
		}

		bool operator<(const string& s) const
		{
			return strcmp(_str, s._str) < 0;
		}

		bool operator==(const string& s) const
		{
			return strcmp(_str, s._str) == 0;
		}

		bool operator<=(const string& s) const
		{
			return *this < s || *this == s;
		}

		bool operator>(const string& s) const
		{
			return !(*this <= s);
		}

		bool operator>=(const string& s) const
		{
			return !(*this < s);
		}

		bool operator!=(const string& s) const
		{
			return !(*this == s);
		}

		void clear()
		{
			_str[0] = '\0';
			_size = 0;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
	public:
		const static size_t npos;
	};

	const size_t string::npos = -1;

	ostream& operator<<(ostream& out, const string& s)
	{
		/*for (size_t i = 0; i < s.size(); i++)
		{
			out << s[i];
		}*/
		for (auto ch : s)
			out << ch;

		return out;
	}

	istream& operator>>(istream& in, string& s)
	{
		s.clear();
		//s.reserve(128);

		char buff[129];
		size_t i = 0;

		char ch;
		ch = in.get();
		while (ch != ' ' && ch != '\n')
		{
			buff[i++] = ch;
			if (i == 128)
			{
				buff[i] = '\0';
				s += buff;
				i = 0;
			}

			//s += ch;

			ch = in.get();
		}

		if (i != 0)
		{
			buff[i] = '\0';
			s += buff;
		}

		return in;
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

langchain 文本向量化存储,并检索相似 topK

目录 chroma 检索 faiss 检索 检索器 相似性 最大相关性mmr 相似数阈值 txt 有多行&#xff0c;我的这份数据有 67 行&#xff0c;样例如下&#xff1a; 字段1\t值1\n 字段2\t值2\n ... chroma 检索 pip install langchain-chroma 在本地下载了 embedding 模型&…

使用SquareLine Studio创建LVGL项目到IMX6uLL平台

文章目录 前言一、SquareLine Studio是什么&#xff1f;二、下载安装三、工程配置四、交叉编译 前言 遇到的问题&#xff1a;#error LV_COLOR_DEPTH should be 16bit to match SquareLine Studios settings&#xff0c;解决方法见# 四、交叉编译 一、SquareLine Studio是什么…

单列模式1.0

单列模式 单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例 1.饿汉模式 只要程序一启动就会立即创建出一个对象 class Signleton{private static Signleton instancenew Signleton();//防止在以后的代码中再创建对象&#xff0c;我们将构造方法private,…

LeetCode 24. 两两交换链表中的节点

解题思路 这道题用画图的方法是比较好的。 相关代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.…

易语言数据库常用操作

易语言是一门中文编程语言&#xff0c;由国人开发&#xff0c;虽然比较冷门&#xff0c;但是在有些场合却非常流行&#xff0c;比如自动化脚本&#xff0c;还有开发外挂。 本文将介绍在易语言数据库的一些常规操作。 1. 打开数据库 2. 关闭数据库 3. 读取数据库 4. 数据库指针…

英伟达高性能芯片供货周期缩短到2-3个月,今年GPU不再紧缺?

戴尔台湾地区总经理Terence Liao近日称&#xff0c;英伟达高性能 AI GPU的交付周期在过去几个月中已从3-4个月缩短到仅2-3个月&#xff0c;进入2024年以来交货等待时间一直在不短缩短&#xff0c;目前的2-3个月已经是英伟达高性能GPU最短的交货期。 英伟达公司正在不断努力提高…

【Sql Server】锁表如何解锁,模拟会话事务方式锁定一个表然后进行解锁

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言创建表模拟…

云服务器环境web环境搭建之JDK、redis、mysql

一、Linux安装jdk&#xff0c;手动配置环境 链接: https://pan.baidu.com/s/1LRgRC5ih7B9fkc588uEQ1whttps://pan.baidu.com/s/1LRgRC5ih7B9fkc588uEQ1w 提取码: 0413 tar -xvf 压缩包名 修改配置文件/etc/profile 二、安装redis环境 方案一&#xff1a; Linux下安装配置r…

计算机操作系统——2 进程与作业

目录 一、程序&#xff08;一&#xff09;概念&#xff08;二&#xff09;程序的执行 二、进程&#xff08;一&#xff09;概念与特征&#xff08;二&#xff09;进程控制块&#xff08;三&#xff09;进程句柄&#xff08;四&#xff09;进程的状态 三、线程四、作业&#xff…

【STL详解 —— list的介绍及使用】

STL详解 —— list的介绍及使用 list的介绍list的介绍使用list的构造list iterator的使用list capacitylist element accesslist modifiers 示例list的迭代器失效 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭…

Socket 通信机制详解

Socket 是网络编程中一种重要的通信机制&#xff0c;它允许不同的计算机通过网络进行数据交换。 一、 Socket 的概念 Socket&#xff08;套接字&#xff09;是计算机网络编程中的一种抽象&#xff0c;它提供了在网络上进行通信的接口。 Socket 本质上是一种通信的端点&#…

基于springboot+vue实现的药品信息管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

java算法day52 | 动态规划part13 ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

300.最长递增子序列 思路&#xff1a; 子序列问题是动态规划解决的经典问题&#xff0c;当前下标i的递增子序列长度&#xff0c;其实和i之前的下表j的子序列长度有关系&#xff0c;那又是什么样的关系呢。 接下来&#xff0c;我们依然用动规五部曲来详细分析一波&#xff1a; …

R:普通分组柱状图

输入文件实例&#xff08;存为csv格式&#xff09; library(ggplot2) library(ggbreak)# 从CSV文件中读取数据 setwd("C:/Users/fordata/Desktop/研究生/第二个想法(16s肠型&#xff0b;宏基因组功能)/第二篇病毒组/result/otherDB") data <- read.csv("feta…

elementui中el-select下拉列表偏移问题

问题截图 解决方法 在el-select中添加:popper-append-to-body"false"即可 加完后的效果

【MATLAB源码-第48期】基于matlab的16QAM信号盲解调仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 16QAM (16个象限幅度调制) 是一种广泛使用的数字调制技术。在无线和有线通信系统中&#xff0c;为了在固定的带宽内发送更多的信息&#xff0c;高阶调制如16QAM被使用。下面是16QAM盲解调的基本步骤、优缺点及应用场景。 16…

Spring Boot 学习(5)——开发流程:快速入门

花了几天的时间&#xff0c;整出个 “hello spring boot”&#xff0c;并且把它从 2 搞到了 3。 纸上得来终觉浅&#xff01;自己实践出真知&#xff01;现在再回头来囫囵一遍&#xff0c;加深下印象。回想下从前自觉某一编程语言大都如此&#xff0c;先找到简单示例照着画一遍…

【音视频流媒体服务端开发学习指南】音视频驱动、多媒体中间件、流媒体服务器的开发,开发过即时通讯+音视频通话的大型项目

音视频流媒体开发是一个涉及多种技术和知识领域的实践领域。以下是一份指南&#xff0c;帮助你系统学习流媒体开发&#xff1a; 理解基础概念&#xff1a; 习关于音视频数据的基础知识&#xff0c;包括常见的音频与视频格式、编解码器(codec)、容器格式等。 了解流媒体的基本工…

操作系统(第四周 第二堂)

目录 回顾 进程运行 进程的创建 进程的工作 举例 进程的删除 举例1&#xff08;走到return 0结束&#xff09; 举例2&#xff08;利用exit&#xff08;1&#xff09;结束&#xff09; 进程通信 共享内存 生产者算法 消费者算法 消息传递 定义 算法实现 总结 回顾…

【Python习题】若一个正整数的逆序数和它自身相等,则该整数称为回文数。编写程序,找出 1000以内的所有回文数。

题干 若一个正整数的逆序数和它自身相等,则该整数称为回文数。编写程序,找出 1000以内的所有回文数。 代码