C++之String类(下)

news2024/12/24 8:18:34

片头

       嗨喽~ 我们又见面啦,在上一篇C++之String类(上)中,我们对string类的函数有了一个初步的认识,这一篇中,我们将继续学习string类的相关知识。准备好了吗?咱们开始咯~

二、标准库中的string类

2.5 string类对象的修改操作
函数名称功能说明
push back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=在字符串后追加字符串str
assign给字符串原有的内容进行覆盖,类似于赋值
insert用于在字符串的pos位置插入一个字符串、字符串的前n个字符或n个字符c
erase用于在字符串的pos位置删除len个字符
replace替换源字符串中的字符
c str返回c格式字符串
rfind + npos从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
swap用于交换2个string类对象
operator+返回一个新构造的string类对象,其值是lhs和rhs的合并
getline用于字符串的输入

(1)push back函数 

我们测试一下:

void test_string15() {
	string s1("hello world");
	cout << s1 << endl;

	//在s1字符串的后面尾插'x'
	s1.push_back('x');
	cout << s1 << endl;
}


(2)append函数

我们测试一下:

void test_string16() {
	string s1("hello world");
	cout << s1 << endl;

	//在s1字符串的后面追加一个字符串
	s1.append(" yyyyyy!!!!");
	cout << s1 << endl;
}

(3)此外,我们还可以使用运算符operator+=函数重载

代码如下:

void test_string17() {
	string s1("hello world");
	cout << s1 << endl;

	string s2("111111");

	//在s1字符串的后面追加一个字符串
	s1 += 'y';
	s1 += "zzzzzzzzzzz";
	s1 += s2;
	cout << s1 << endl;
}

注意:

①在string尾部追加字符时,s.push_back(c)/s.append(1,c)/s += 'c' 三种的实现方式差不多,一般情况下,string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串

②对string操作时,如果能够大概预估到放多少字符,可以先通过reverse把空间预留好


(4)assign函数

assign函数类似于给字符串原有的内容进行覆盖,类似于赋值

void test_string18() {
	string s1("hello world");
	cout << s1 << endl;

	s1.assign("11111");
	cout << s1 << endl;
}

  


 (5)insert函数

①在s1字符串前头插"xxxxx"  

void test_string19() {
	string s1("hello world");
	cout << s1 << endl;

	//在s1字符串前头插"xxxxx"
	s1.insert(0, "xxxxx");
	cout << s1 << endl;
}

 ②在s1字符串前头插一个字符'y'

void test_string20() {
	string s1("hello world");
	cout << s1 << endl;

	//在s1字符串前头插单个字符'y'
	s1.insert(0, 1,'y');
	cout << s1 << endl;
}

③使用迭代器,在s1字符串钱头插单个字符'y'

void test_string21() {
	string s1("hello world");
	cout << s1 << endl;

	//在s1字符串前头插单个字符'y'
	s1.insert(s1.begin(), 'y');
	cout << s1 << endl;
}

  ④在s1字符串前插入s2字符串,二者都采用迭代器的形式

void test_string22() {
	string s1("hello world");
	cout << s1 << endl;

	string s2("11111");

	//在s1字符串前头插s2字符串
	s1.insert(s1.begin(),s2.begin(),s2.end());
	cout << s1 << endl;
}


 (6)erase函数

①当pos=0,len=1,说明,从下标为0的元素开始,删除1个字符

void test_string23() {
	string s1("hello world");
	cout << s1 << endl;
	
	//从下标为0的元素开始,删除1个字符
	s1.erase(0, 1);
	cout << s1 << endl;
}

  

②当我不传第二个参数的时候,len默认为npos

void test_string24() {
	string s1("hello world");
	cout << s1 << endl;

	//省略第二个参数
	//默认删除从下标为4后的所有元素
	//包括下标为4的元素
	s1.erase(4);
	cout << s1 << endl;
}

③当我传入的第二个参数len大于字符串本身的长度时

void test_string25() {
	string s1("hello world");
	cout << s1 << endl;

	//从下标为3的位置开始,
	//删除100个元素
	s1.erase(3, 100);
	cout << s1 << endl;
}

 

另外,使用erase函数时,第二个参数len可以不合法,但是第一个参数pos必须合法!


(7)replace函数

哇哦,咋一看,这个函数怎么有这么多的用法?!

不慌,我们慢慢来看~

 ①string& replace(size_t pos,size_t len,const string& str);

void test_string27() {
	string s1("hello world");
	cout << s1 << endl;

	//将下标为5的位置,1个字符
	//替换为20%
	s1.replace(5, 1, "20%");
	cout << s1 << endl;
}

小练习:将下面字符串中出现的空白字符替换为"20%"

void test_string28() {
	string s1("hello world hello bit");
	cout << s1 << endl;

	for (int i = 0; i < s1.size();) {
		if (s1[i] == ' ') {
			s1.replace(i, 1, "20%");
			i += 3;
		}
		else {
			i++;
		}
	}
	cout << s1 << endl;
}

或者可以用另一种解法:

void test_string29() {
	string s1("hello world hello bit");
	cout << s1 << endl;

	string s2;
	//使用范围for
	for (auto e : s1) {
		if (e != ' ') {
			s2 += e;
		}
		else {
			s2 += "20%";
		}
	}
	cout << s2 << endl;
}

(8) c_str函数

const char* c_str() const;

 按照C语言的格式返回字符串

例如:

void test_string38() {
	string s1("hello");
	s1 += '\0';
	s1 += "world";

	cout << s1 << endl;
	cout << s1.c_str() << endl;
}

在hello后面加上'\0'和字符串world,重载后的流插入操作符函数会按照size的大小来打印字符串

而打印c_str的返回值,会遇到'\0'就停下

(9) rfind + npos函数

size_t rfind(char c,size_t pos = npos)const;

static const size_t npos = -1;

从字符串的pos位置向前找字符c,返回该字符在字符串中的位置

npos是string类中定义的一个静态成员变量,类型为无符号整型,值为-1,因为是无符号转换后变成整型的最大值,也就是4294967295(42亿多) ,当我们不给pos的值,按照缺省值执行,默认从字符串尾部开始寻找。

例如:

void test_string39() {
	string s1("hello");
	//从后往前寻找第一次出现的'l'
	cout << s1.rfind('l') << endl;
}

(10) find函数

size_t find (char c,size_t pos = 0) const;

 从字符串的pos位置向后找字符c,返回该字符在字符串中的位置

例如:

void test_string40() {
	string s1("hello");
	//从前往后寻找第一次出现的'e'
	cout << s1.find('e') << endl;
}

 (11)substr函数

string substr (size_t pos = 0,size_t len = npos);

 在str中从pos位置开始,截取len个字符,然后将其返回

例如:

void test_string41() {
	string s1("hello world!");
	//从下标为0的元素开始,截取5个字符
	string s2 = s1.substr(0, 5);
	cout << s2 << endl;
}

(12) swap函数

void swap (string& str);

用于交换2个string类对象

string类中的swap函数相比标准库中的swap函数,交换string类对象的效率更高

例如:

void test_string42() {
	string s1("hello");
	string s2("world!");
	//将s1字符串和s2字符串进行交换
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;
}

(13) operator+ 函数

string operator+ (const string& lhs,const string& rhs);

string operator+ (const string& lhs,const char* rhs);

string operator+ (const char* lhs,const char* rhs);

string operator+ (const string& lhs,char rhs);

string operator+ (char lhs,const string& rhs);

 返回一个新构造的string类对象,其值是lhs和rhs的合并

例如:

void test_string43() {
	string s1("hello");
	string s2("world!");
	string s3;

	s3 = s1 + s2;
	cout << s3 << endl;

	s3 = s1 + "123";
	cout << s3 << endl;

	s3 = "123" + s2;
	cout << s3 << endl;

	s3 = s1 + "x";
	cout << s3 << endl;

	s3 = 'x' + s1;
	cout << s3 << endl;
}

(14)getline函数

istream& getline(istream& is,string& str,char delim);

istream& getline(istream& is,string& str);

 用于字符串的输入

相比cin遇到空格就停止读取,我们可以给出分隔符delim,遇到delim才停止读取。如果没有给出,则遇到换行停止读取。

例如:

void test_string44() {
	string s1;
	//没有给出分隔符delim
	//遇到换行,停止读取
	getline(cin, s1);
	cout << s1 << endl;

	//给出分隔符'%'
	//遇到分隔符,停止读取
	getline(cin, s1, '%');
	cout << s1 << endl;
}

 

2.6 各种运算符重载函数

(1)operator>>和operator<<

istream& operator>>(istream& is,string& str);

ostream& operator<<(ostream& os,const string& str);

用于string对象的流提取和流插入

例如:

void test_string45() {
	string s1;
	cin >> s1;
	cout << s1 << endl;
}

 

(2)比较运算符

用于比较2个字符串的对应位置的ASCII码值大小

例如:

void test_string46() {
	string s1("abcde");
	string s2("bbcde");

	cout << (s1 > s2) << endl;
	cout << (s1 >= s2) << endl;
	cout << (s1 < s2) << endl;
	cout << (s1 <= s2) << endl;
	cout << (s1 == s2) << endl;
	cout << (s1 != s2) << endl;
}


刚刚我们学习了这么多的函数,一起来练练几道题吧~

小练习1:反转字符串

emmm,这道题是想表达什么意思呢?举2个例子吧~

OK,本题分析完成,具体代码如下:

class Solution {
public:
    void reverseString(vector<char>& s) {
        int begin = 0;          //begin从下标为0的位置开始
        int end = s.size()-1;   //end从最后一个元素的下标开始

        while(begin < end)      //当begin和end相遇时,退出循环
        {
            //交换
            int temp = s[begin];
            s[begin] = s[end];
            s[end] = temp;

            begin++;            //begin更新    
            end--;              //end更新
        }
    }
};

小练习2:仅仅反转字母

emmm,这道题和上面反转字符串很像,但是不太一样,因为这道题,字符串里面不仅有字母,还有其他符号。我们要做的,只是将字母反转,其他符号的位置不变。

第一步,我们首先要判断当前字符是否为字母还是其他符号:

//判断当前字符是否为字母
//注意:用短路或来连接
bool isLetter(char c)
{
        return c >= 'A' && c <= 'Z'
    ||         c >= 'a' && c <= 'z';
}

第二步,反转字母(定义begin和end,如果遇到字母,进行交换,否则直接跳过)

string reverseOnlyLetters(string s) {
        int begin = 0;          //begin指向第一个元素的位置
        int end = s.size()-1;   //end指向最后一个元素的位置

        while(begin < end)      //当begin和end相遇时,退出循环
        {   
            //当前字符不是字母,直接跳过,不需要反转
            while(begin < end && !isLetter(s[begin]))
            {
                begin++;
            }
            while(begin < end && !isLetter(s[end])){
                end--;
            }

            //当前字符为字母,需要反转,进行交换
            int temp = s[begin];
            s[begin] = s[end];
            s[end] = temp;

            //交换完毕后,begin更新,end也更新
            begin++;
            end--;
        }

        return s;   //最后返回s字符串
    }

小练习3:字符串中的第一个唯一字符

emmm,举个例子呗~

另外,这道题特别说明了:1<=s.length<=10^5,s只包括小写字母

第一步,我们需要给26个小写字母开辟数组,数组的类型为int(开辟空间足够大)

 //给26个小写字母开辟空间,初始化为0
 int count[26] = {0};

第二步,我们需要统计字符串中的每个字符出现的次数

//利用范围for,统计字符串中的每个字符出现的次数
//这里的count数组里面的元素是按照顺序的
//比如:下标为0是'a',下标为1是'b',下标为2是'c'

  for(auto e: s){
   count[e-'a']++;
}

第三步:遍历s字符串,找出第一次出现唯一字符

 //遍历s字符串,找出第一次出现的唯一字符
        //如果找到了,立即返回下标
        for(int i = 0;i<s.size();i++){
            if(count[s[i]-'a'] == 1){
                return i;
            }
        }
        //如果没有找到,返回-1
                return -1;

OK,本题完整代码如下:

class Solution {
public:
    int firstUniqChar(string s) {
        //给26个小写字母开辟空间,初始化为0
        int count[26] = {0};

        //利用范围for,统计字符串中的每个字符出现的次数
        //这里的count数组里面的元素是按照顺序的
        //比如:下标为0是'a',下标为1是'b',下标为2是'c'
        for(auto e: s){
            count[e-'a']++;
        }

        //遍历s字符串,找出第一次出现的唯一字符
        //如果找到了,立即返回下标
        for(int i = 0;i<s.size();i++){
            if(count[s[i]-'a'] == 1){
                return i;
            }
        }
        //如果没有找到,返回-1
                return -1;
    }
};

方法二:直接将字符串放入另一个数组中,统计字符串中的第一个唯一字符

class Solution {
public:
    int firstUniqChar(string s) {
        //开辟数组,初始化为0
        int count[256] = {0};

        //将s字符串里面的每一个元素都放入数组
        //相同的字符,每放入1次,该下标对应的值自增1次
        for(int i = 0; i<s.size();i++){
            count[s[i]]++;
        }

        //遍历s字符串,找出第一次出现的唯一字符
        for(int i = 0;i<s.size();i++){
            if(count[s[i]] == 1){
                return i;
            }
        }
        return -1;
    }
};

小练习4:验证回文串

emmm,举个例子吧~

第一步:判断是否为字母数字字符

    //1.判断是否为字母数字字符
    bool isLetterOrNumber(char c){
        return c >= '0' && c <= '9'
        ||     c >= 'a' && c <= 'z'
        ||     c >= 'A' && c <= 'Z';
    }

第二步:将所有的大写字母转换为小写字母(使用范围for时,必须传引用,这样才能保证修改e的同时,修改源字符串)

         //1.大写字符转换为小写字符
         for(auto& e:s){
            if(e >= 'A' && e<= 'Z'){
                e += 32;
            }
         }

第三步:验证是否为回文串

 //2.验证是否为回文串
         int begin = 0;         //begin指向第一个元素
         int end = s.size()-1;  //end指向最后一个元素

         while(begin < end)     //当begin和end相遇时,循环停止
         {
            //遇到非字母数字字符时,直接跳过
            while(begin < end && !isLetterOrNumber(s[begin])){
                begin++;
            }
            while(begin < end && !isLetterOrNumber(s[end])){
                end--;
            }

            //2个字母数字字符进行比较
            //如果不相同,返回false
            //如果相同,begin++,end--
            if(s[begin] != s[end]){
                return false;
            }else{
                begin++;
                end--;
            }
         }
            //比较完毕,begin和end指向的元素都相同,返回true
         return true;

OK,本题完整代码如下:

class Solution {
public:
    //1.判断是否为字母数字字符
    bool isLetterOrNumber(char c){
        return c >= '0' && c <= '9'
        ||     c >= 'a' && c <= 'z'
        ||     c >= 'A' && c <= 'Z';
    }
    bool isPalindrome(string s) {
         //1.大写字符转换为小写字符
         for(auto& e:s){
            if(e >= 'A' && e<= 'Z'){
                e += 32;
            }
         }

         //2.验证是否为回文串
         int begin = 0;         //begin指向第一个元素
         int end = s.size()-1;  //end指向最后一个元素

         while(begin < end)     //当begin和end相遇时,循环停止
         {
            //遇到非字母数字字符时,直接跳过
            while(begin < end && !isLetterOrNumber(s[begin])){
                begin++;
            }
            while(begin < end && !isLetterOrNumber(s[end])){
                end--;
            }

            //2个字母数字字符进行比较
            //如果不相同,返回false
            //如果相同,begin++,end--
            if(s[begin] != s[end]){
                return false;
            }else{
                begin++;
                end--;
            }
         }
            //比较完毕,begin和end指向的元素都相同,返回true
         return true;
    }
};

小练习5:字符串相加

emmm,举个例子吧~

面对这种题,该怎么做呢?

题目要求:不能使用任何内建的用于处理大整数的库,也不能直接将输入的字符串转换为整数形式

那我们可以把字符串拆成个位,十位,百位......然后将个位和个位相加,十位和十位相加,百位和百位相加

第一步:我们先将num1和num2字符串的最后一个元素取出来,保存到end1和end2

    int end1 = num1.size()-1;//end1保存的是num1字符串的最后一位(个位)
    int end2 = num2.size()-1;//end2保存的是num2字符串的最后一位(个位)

第二步:假设变量next表示进位,字符串s表示累加的最终结果。我们将num1和num2的个位数由字符转换为数字,进行相加,注意要处理进位的情况。

            int next = 0;   //进位
            string s;       //返回的最终结果

        //当end1和end2都不存在时,退出循环,用短路或来连接
    while(end1 >= 0 || end2 >= 0)
    {
        int x1 = end1 >= 0 ? num1[end1--]-'0' : 0;//x1表示把当前字符转换为数字
        int x2 = end2 >= 0 ? num2[end2--]-'0' : 0;//x2表示把当前字符转换为数字
        int x = x1+x2+next;//x表示2个位数进行累加的结果

                next = x/10;      //进位
                x = x % 10;       //对应位上的数

                s.insert(0,1,'0'+x);//头插,将数字转换为字符
              //s.insert(s.begin(),'0'+x);//使用迭代器
     }

            if(next == 1)       //当进位为1,直接在字符串s的前面头插"1"
            {
                s.insert(0,1,'1');
             // s.insert(s.begin(),'0'+x);//使用迭代器
            }

            return s;           //返回s字符串

OK,这道题我们解决了,完整代码如下:

class Solution {
public:
    string addStrings(string num1, string num2) {
    int end1 = num1.size()-1;//end1保存的是num1字符串的最后一位(个位)
    int end2 = num2.size()-1;//end2保存的是num2字符串的最后一位(个位)

            int next = 0;   //进位
            string s;       //返回的最终结果

        //当end1和end2都不存在时,退出循环,用短路或来连接
while(end1 >= 0 || end2 >= 0){
int x1 = end1 >= 0 ? num1[end1--]-'0' : 0;//x1表示把当前字符转换为数字
int x2 = end2 >= 0 ? num2[end2--]-'0' : 0;//x2表示把当前字符转换为数字
int x = x1+x2+next;//x表示2个位数进行累加的结果

                next = x/10;      //进位
                x = x % 10;       //对应位上的数

                s.insert(0,1,'0'+x);//头插,将数字转换为字符
              //s.insert(s.begin(),'0'+x);//使用迭代器
            }

            if(next == 1)       //当进位为1,直接在字符串s的前面头插"1"
            {
                s.insert(0,1,'1');
              // s.insert(s.begin(),'0'+x);//使用迭代器
            }

            return s;           //返回s字符串
    }
};

不过,每次插入要挪动数据,插入N次,挪动次数合计是等差数列。头插的时间复杂度为O(n^2),我们可以选择尾插,最后逆置。


片尾

今天我们把string类的函数掌握的差不多了,又练习了几道题,希望对大家有所帮助!!!

点赞收藏加关注!!!

谢谢大家!!!

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

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

相关文章

业务封装与映射 -- AMP BMP GMP

概述 不同单板支持不同的封装模式&#xff0c;主要包括: AMP (Asynchronous Mapping Procedure&#xff0c;异步映射规程)BMP (Bit-synchronous Mapping Procedure&#xff0c;比特同步映射规程)GMP (Generic Mapping Procedure&#xff0c;通用映射规程) AMP/BMP&#xff1a…

Qt_绘图

目录 1、绘图核心类 2、QPainter类的使用 2.1 绘制线段 2.2 绘制矩形 2.3 绘制圆形 2.4 绘制文本 3、QPen类的使用 3.1 使用画笔 4、QBrush类的使用 4.1 使用画刷 5、绘制图片 5.1 测试QPixmap 5.1.1 图片移动 5.1.2 图标缩小 5.1.3 旋转图片 5.1.4 将…

【逐行注释】MATLAB下的粒子滤波代码(三维状态与观测,可直接复制粘贴到MATLAB上面运行)

文章目录 程序设计1. 介绍2. 系统模型3. 算法步骤源代码(直接复制到MATLAB上面可以运行)运行结果程序设计 1. 介绍 粒子滤波(Particle Filter, PF)是一种基于贝叶斯理论的递归估计方法,广泛用于动态系统状态的估计和跟踪。该方法通过一组粒子(即假设的状态)及其权重来…

【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-1

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

5款惊艳全网的AI写作论文神器!从此告别写作烦恼!

在当今的学术研究和写作领域&#xff0c;撰写高质量的论文是一项挑战性的任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;AI论文写作工具逐渐成为帮助学者和学生提高写作效率的重要工具。这些工具不仅能够提高写作效率&#xff0c;还能帮助研究者生成高质量的论…

ECharts 快速使用

最终效果 使用介绍 echarts图表的绘制&#xff0c;大体分为三步&#xff1a; 根据 DOM实例&#xff0c;通过 echarts.init方法&#xff0c;生成 echarts实例构建 options配置对象&#xff0c;整个echarts的样式&#xff0c;皆有该对象决定最后通过实例.setOption方法&#xf…

【测试-BUG篇】软件测试的BUG知识你了解多少呢?

文章目录 1. 软件测试的生命周期2. BUG3. BUG的生命周期4. 与开发人员起争执怎么办 1. 软件测试的生命周期 &#x1f34e;软件测试 贯穿整个软件的生命周期&#xff1b; &#x1f34e;软件测试的生命周期是指测试流程&#xff1b; ①需求分析 用户角度&#xff1a;软件需求是…

C++:一文搞懂友元类(friend class)

C的友元&#xff08;friend&#xff09;是个很重要的概念&#xff0c;好些朋友对此却很迷惑&#xff0c;本文将对友元类&#xff08;friend class&#xff09;详细讲解&#xff0c;一文搞懂。 友元的特性&#xff1a; 1、使用friend修饰的友元类可以访问本类的私有成员(priva…

中国电信解锁万亿参数大模型:TeleAI的创新与突破

首个由万卡集群训练出来的万亿参数大模型&#xff0c;已被一家央企解锁。 具体而言&#xff0c;为了推动纯国产人工智能的探索&#xff0c;带来这条新路径的正是中国电信人工智能研究院&#xff08;TeleAI&#xff09;。 该研究院由中国电信集团的CTO、首席科学家兼院长李学龙…

坡印廷矢量(也叫功率流密度,对面积积分就是功率)

坡印廷矢量在静电场&#xff0c;静磁场&#xff0c;恒定电流的电场&#xff0c;和时变电磁场中的表达式不同。 我们看时变电磁场的坡印廷矢量 坡印廷矢量就等于这个&#xff0c;其中的电场和磁场是实数表示的 坡印廷矢量用复数形式的场求 这里的E和H是复数表示的场&#xff0…

电影票接口api对接有哪些优势?

一、业务功能拓展方面的优势 多平台整合可以整合多个影院票务系统&#xff0c;通过一个接口获取众多影院的信息&#xff0c;包括影院、影厅、座位、影片、场次、日期及票价等信息&#xff0c;方便在自己的应用程序中展示这些信息&#xff0c;从而实现电影票的在线预订、支付和…

人工智能价格战——如何降低成本让人工智能更易于普及

十年前&#xff0c;开发人工智能 (AI) 是只有大公司和资金充足的研究机构才能负担得起的事情。必要的硬件、软件和数据存储成本非常高。但从那时起&#xff0c;情况发生了很大变化。一切始于 2012 年的 AlexNet&#xff0c;这是一种深度学习模型&#xff0c;展示了神经网络的真…

微服务jvisualvm解析部署使用全流程

1、介绍 VisualVM 是Netbeans的profile 2、启动 进入正在使用的jdk下bin目录&#xff0c;运行jvisualvm.exe。 3、选中要监控的线程 4、安装gc插件 5、插件安装报错 VisualVM: Plugins Centers 访问这个地址&#xff0c;找到对应版本再配置 https://visualvm.github.io/uc/…

【CKA】六、四层负载-Service应用

6、四层负载-Service应用 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 1、编辑front-end的deploy服务&#xff0c;添加端口信息 2、暴露svc端口 3. 官网地址&#xff1a; https://kubernetes.io/zh-cn/docs/tutorials/services/connect-applications-service/#the-ku…

nominatim部署OSM离线地图

第一步&#xff1a;准备一个大内存的服务器&#xff0c;磁盘PG大小根据实际导入的数据确定&#xff0c;全量数据1T&#xff0c;osm.pdf属于压缩文件&#xff0c;如果能下载&#xff0c;但下载很慢&#xff0c;可以尝试用迅雷下载。 osm.pdf下载 osm.pdf另外一个下载路径 全量数…

学生党有福了!国内最好的4款AI论文润色机构

在当今学术研究和写作领域&#xff0c;AI技术的应用已经变得越来越普遍。AI论文润色工具不仅能够帮助研究人员快速生成论文草稿&#xff0c;还能进行内容优化、查重和排版等操作。这些工具极大地提高了写作效率和质量&#xff0c;尤其对于学生党来说&#xff0c;选择合适的AI论…

基于单片机多功能称重系统设计

** 文章目录 前言概要功能设计设计思路 软件设计效果图 程序文章目录 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对…

2024年3分钟手把手教你激活Guitar Pro 8破解版

Guitar Pro是一款专业的吉他制谱软件&#xff0c;现在已更新至Guitar Pro8&#xff0c;新增了支持添加音频轨道、支持嵌套连音符、直观的效果器视图、让指法一目了然的音阶示意图等实用新功能。下面我们来看Guitar Pro8 Windows如何安装激活。 GuitarPro8安装包和许可证密钥夸克…

Acwing 高斯消元

高斯消元能在 O ( n 3 ) O(n^3) O(n3)的时间复杂度内求解n个方程&#xff0c;n个未知数的多元线性方程组&#xff0c;即 a 11 x 1 a 12 x 2 a 13 x 3 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 a 23 x 3 ⋯ a 2 n x n b 2 … a n 1 x 1 a n 2 x 2 a n 3 x 3 ⋯ a n n…

STM32CubeMX工程printf问题

1、不能打印输出的问题 利用STM32CubeMX创建了一个带FreeRTOS系统的工程&#xff0c;使能多线程保护。 然后在任务函数中调用了printf函数。 可是电脑的串口上没有信息输出&#xff0c;程序进入了硬件错误中断。 原来是因为自动生成的串口初始化函数MX_LPUART1_UART_Init中&a…