模板初阶以及string类使用

news2024/11/23 11:33:57

模板初阶以及string类使用

    • 模板的简单认识
      • 1.泛型编程
      • 2.函数模板
        • 模板的原理图
        • 函数模板格式
        • 函数模板实例化
        • 非模板函数和模板函数的匹配原则
      • 3.类模板
        • 类模板的定义格式
        • 类模板的实例化
    • string
      • 1.string简介
      • 2.string常用的接口
    • 题目练习
      • 1.字符串相加
      • 2.字符串里面最后一个单词的长度
      • 3.翻转字符串区间

模板的简单认识

1.泛型编程

泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。

实现加法:

//不使用模板,只使用函数重载,每一个需要的类型都需要写一份函数
int add(int a, int b)
{
	return a + b;
}

double add(double a, double b)
{
	return a + b;
}

int main()
{
	int a1 = 0;
	int b1 = 0;
	int c1 = add(a1, b1);

	double a2 = 0.1;
	double b2 = 0.5;
	double c2 = add(a2, b2);
	return 0;
}

两个函数只有类型上的不同,逻辑完全一致,能不能写一份表示逻辑的模板,让编译器帮我们生成函数呢?

2.函数模板

模板的原理图

模板的原理


函数模板格式

template<typename T1, typename T2,…,typename Tn>
返回值类型 函数名(参数列表){}

用函数模板来实现加法:

//模板不是具体的函数,真正的函数是由编译器去生成的
template<typename T>
T add(T a,T b)
{
	return a + b;
}
//typename是用来定义模板参数的关键字,也可以用class

int main()
{
	int a1 = 0;
	int b1 = 0;
	int c1 = add(a1, b1);

	double a2 = 0.1;
	double b2 = 0.5;
	double c2 = add(a2, b2);
	return 0;
}

函数模板实例化

  1. 隐式实例化:由编译器依据实参来自行生成。
template<typename T>
T add(T a,T b)
{
	return a + b;
}

int main()
{
	int a1 = 0;
	int b1 = 0;
	int c1 = add(a1, b1);//编译器生成int add(int a, int b);

	double a2 = 0.1;
	double b2 = 0.5;
	double c2 = add(a2, b2);//编译器生成double add(double a, double b);
	return 0;
}
  1. 显示实例化:在函数名后的<>中指定模板参数的实际类型

下面这个例子不显示实例化就会报错:

template<typename T>
T add(T a,T b)
{
	return a + b;
}

int main()
{
	int a1 = 0;
	double b1 = 0.5;
	int c1 = add(a1, b1);
	//模板中两个参数类型是一致的,这里一个int,一个double,没有明确指定编译器无法生成函数
	return 0;
}

在这里插入图片描述
利用显示实例化解决:

template<typename T>
T add(T a,T b)
{
	return a + b;
}

int main()
{
	int a1 = 0;
	double b1 = 0.5;
	double c1 = add<double>(a1, b1);
	//指定生成double add(double a,double b)并调用,和正常函数一样这里会进行隐式类型转换
	return 0;
}

非模板函数和模板函数的匹配原则

  1. 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数
//专门处理int
int add(int a, int b)
{
	return a + b;
}
//通用的函数模板
template<typename T>
T add(T a,T b)
{
	return a + b;
}

int main()
{
	int a1 = 0;
	int b1 = 5;
	int c = add(a1, b1);//与非模板函数完全匹配,编译器不会生成
	c = add<int>(a1, b1); //指定编译器生成并调用
	//两个函数同时存在不冲突	
	return 0;
}
  1. 对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
//专门处理int
int add(int a, int b)
{
	return a + b;
}
// 通用加法函数
template<class T1, class T2>
T1 add(T1 left, T2 right)
{
	return left + right;
}
int main()
{
	add(1, 2); // 与非函数模板类型完全匹配,不需要函数模板实例化
	add(1, 2.0); // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add函数
	return 0;
}

3.类模板

类模板的定义格式

template<class T1, class T2, …, class Tn>
class 类模板名
{
// 类内成员定义
};

//和函数模板一样,这里并不是真正的类
template<class T>
class A
{
public:
	A(T a)
		:_a(a)
	{}
	//演示一下定义声明分离
	T get();
private:
	T _a;
};

// 注意:类模板中函数放在类外进行定义时,需要加模板参数列表
template <class T>
T A<T>::get()
{
	return _a;
}

类模板的实例化

  类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

int main()
{
	//A是类名,A<int>才是类型
	A<int> a(5);
	A<double> b(5.22);
	return 0;
}

string

1.string简介

在这里插入图片描述

  1. string是表示字符串的字符串类
  2. string类是basic_string模板类的一个实例,即typedef basic_string<char> string
  3. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  4. string是一个顺序容器,会自动扩容

2.string常用的接口

string类中有一个静态成员npos:static const size_t npos = -1;
本文只讲使用,不讲底层原理

  1. string类对象的常见构造
函数名称功能说明
string()
(常用)
构造空的string类对象,即空字符串
string(const char* s)
(常用)
用C字符串来构造对象
string(size_t n, char c)string类对象中前n个字符初始化为C
string(const string&s)
(常用)
拷贝构造
int main()
{
	string s1; // 构造空的string类对象s1
	string s2("hello"); // 用C格式字符串构造string类对象s2
	string s3(s2); // 拷贝构造s3
	return 0;
}

  1. string类对象的容量操作
函数名称功能说明
size_t size()
(常用)
返回有效字符数('\0’不算有效字符)
size_t length()和size()功能一致
size_t capacity()返回可存储有效字符的空间总大小,'\0’不算
bool empty()
(常用)
检查是否为空串,是返回true,否则返回false
void clear()
(常用)
清空字符串,变成空串
void reserve
(size_t n = 0)
(常用)
预留空间,n大于容量时扩容,不然什么都不做
void resize
(size_t n, char c)
n>有效字符数时从从字符串尾开始填充c直到字符串满;n>容量就先扩容再填充;n<有效字符数时缩短字符串,保留前n个字符。
int main()
{
	string s2("hello"); 
	cout << s2.empty() << endl;
	s2.clear();//调用clear清理
	cout << s2.empty() << endl;

	cout << "capacity:" << s2.capacity() << endl;
	s2.reserve(100);//调用reserve预留空间
	cout << "reserve_capacity:" << s2.capacity() << endl;

	s2.resize(50, 'c');//填充
	cout << "s2:" << s2 << endl;

	s2.resize(10);//缩短到10字符
	cout << "s2:" << s2 << endl;
	return 0;
}

  1. string类对象的访问及遍历操作
函数名称功能说明
(const)char& operator ()运算符重载,可以像数组一样通过下标访问字符
(const_)iterator begin()和end()begin取第一个字符位置的迭代器,end取最后一个字符的下一个位置的迭代器(大家可以把迭代器想成指针,后面使用大家就明白了)
(const_)reverse_iterator rbegin()和rend()反向迭代器,使用和begin()一致,方向相反
范围forC++11支持,底层是迭代器
int main()
{
	string s2("hello"); 
	//利用[]运算符重载遍历
	for (int i = 0; i < s2.size(); i++)
		cout << s2[i];
	cout << endl;

	//利用迭代器进行遍历,利用auto自动推导类型
	//这里是std::string::iterator
	auto it = s2.begin();
	while (it != s2.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;

	//反向迭代器遍历
	//这里是std::string::reverse_iterator
	auto rit = s2.rbegin();
	while (rit != s2.rend())
	{
		cout << *rit ;
		rit++;
	}
	cout << endl;

	//范围for遍历
	for (auto ch : s2)
		cout << ch ;
	cout << endl;
	//修改
	for (auto& ch : s2)
		cout << ch ;
	return 0;
}

  1. string类对象的修改操作
函数名称功能说明
void push_back(char c)尾插一个字符c
string& append
(const char* s)
尾插一个字符串
string& operator+=()
(常用)
既可尾插字符串,也可单个字符,非常好用
const char* c_str()
(常用)
返回C格式字符串首地址
size_t find
(char c,size_t pos = 0)
(常用)
从pos位置开始寻找第一个出现c的位置并返回,否则返回npos
size_t rfind
(char c,size_t pos = npos)
从pos位置开始向前寻找第一次出现c的位置并返回,否则返回npos;当pos大于等于长度时,从尾开始向前搜索。(一般就是用这个函数搜索单个字符最后出现的位置)
string substr
(size_t pos = 0, size_t len = npos)
从pos位置开始截取len个字符,如果截取长度大于后面长度,就截取到字符串尾部结束,然后返回
1.string& insert
(size_t pos, size_t n, char c)
2.string& insert
(size_t pos, const char* s)
1.在pos位置插入n个c
2.在pos位置插入C格式字符串
int main()
{
	string s2("hello "); 
	s2.push_back('w');
	s2.append("or");
	s2 += 'l';
	s2 += "dd!";

	cout << s2.c_str() << endl;
	
	cout << "pos(find):" << s2.find('w') << endl;
	cout << "pos(rfind):" << s2.rfind('d') << endl;
	
	if (s2.find('k') == std::string::npos)
		cout << "没找到" << endl;

	string sub = s2.substr(6, 6);
	cout << sub.c_str() << endl;
	//这里相当于头插'c'
	s2.insert(0,1,'c');
	s2.insert(2,"hello ");
	return 0;
}

  1. string类非成员函数
函数功能说明
string operator+()先拷贝一份,实现尾插后返回,不改变原对象
operartor>>()
(常用)
输入运算符重载
operator<<()
(常用)
输出运算符重载
istream& getline
(istream& is, string& str)
读取一行字符,遇到’\n’才结束
bool operator>()    
(<,<=,>=,==,!=)
进行字符串比较
int main()
{
	string s2("hello "); 
	string s3 = s2 + "world";
	cout << "s3:" <<  s3 << endl;

	cin >> s3;
	cout << "s3:" << s3 << endl;

	getchar();
	getline(cin, s3);//可以读取空格
	cout << "s3:" << s3 << endl;

	string s("hello");
	string s1("hellO");
	if (s == s1)
		cout << "s == s1" << endl;
	else if (s > s1)
		cout << "s > s1" << endl;
	else if (s < s1)
		cout << "s < s1" << endl;
	
	return 0;
}

题目练习

1.字符串相加

链接 :字符串相加


题目要求:
在这里插入图片描述


题解:
在这里插入图片描述

class Solution {
public:
    string addStrings(string num1, string num2) 
    {
        //用来遍历
        int end1 = num1.size()-1;
        int end2 = num2.size()-1;
        //用来记录进位
        int flag = 0;
        int sum = 0;
        string str;
        while(end1 >= 0 || end2 >= 0)
        {
            //只有不越界的情况才给值,否则给0
            int x1 = end1>=0?num1[end1]-'0':0;
            int x2 = end2>=0?num2[end2]-'0':0;
            sum = flag + x1 + x2;
            //这里使用尾插,头插效率比较慢
            str += ('0'+sum%10);
            flag = sum/10;
            end1--;
            end2--;
        }

        //还需要处理一种特殊情况,比如"9"+"1",同时结束刚好进位,需要补1
        if(flag == 1)
            str += '1';

        //数据是尾插的,需要逆置
        //reverse属于stl中的算法
        //只需要传入迭代器区间就能实现逆置
        reverse(str.begin(),str.end());
        return str;
    }
};

2.字符串里面最后一个单词的长度

链接:字符串里面最后一个单词的长度


题目要求:
在这里插入图片描述


题解:

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

int main() 
{
    string str;
    getline(cin,str);
    //直接调用rfind找最后一个空格的位置
    //没有找到说明只有一个单词,直接返回长度
    int pos = str.rfind(' ');
    if(pos == std::string::npos)
        cout << (str.size()) << endl;
    else
        cout << (str.size()-(pos+1));
}

3.翻转字符串区间

链接:翻转字符串区间


题目要求:
在这里插入图片描述


题解:

class Solution 
{
public:
    string reverseStr(string s, int k) 
    {
        int index1 = 0;
        int index2 = k-1;
        //每2k个字符中反转前k个字符
        //"abcdefg" ->前4个反转前2个,"abcd"->"bacd","efg"->"feg"
        while(index2 <= s.size()-1)
        {
            reverse(s.begin()+index1,s.begin()+index2+1);
            index1 += 2*k;
            index2 += 2*k;
        }
        //最后一段小于k的全部反转
        reverse(s.begin()+index1,s.end());
        return s;
    }
};

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

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

相关文章

Openlayers实战:使几何图形适配窗口

Openlayers开发的项目中,有一种应用非常重要,就是绘制或者显示出几何图形后,让几何图形居中并适配到窗口下,这样能让用户很好的聚焦到所要看的内容中去。 这里使用了fit的这个view 的方法,具体的操作请参考示例源代码。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozh…

DPR-100-N-H-24插装式直动可调式减压阀

DPR-100-N-H-2,DPR-100-N-S-24,DPR-100-N-H-9,DPR-100-N-H-24,DPR-100-N-S-9,DPR-100-N-H-2直动式可调型电磁阀被设计用于调节副回路常压。 动作状况 DPR-100 稳态时&#xff0c;弹赞栓3打开&#xff0c;允许介质在1和2之间双向流动。当1处达到预设压力时&#xff0c;螺线节流…

机器学习基础08-回归算法矩阵分析(基于波士顿房价(Boston House Price)数据集)

回归算法通常涉及到使用矩阵来表示数据和模型参数。线性回归是最常见的回归算法之一&#xff0c;它可以用矩阵形式来表示。 考虑一个简单的线性回归模型&#xff1a; y m x b y mx b ymxb&#xff0c;其中 y y y 是因变量&#xff0c; x x x 是自变量&#xff0c; m m m 是…

Trie存储和查找字符串

一、链接 835. Trie字符串统计 二、题目 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 xx&#xff1b;Q x 询问一个字符串在集合中出现了多少次。 共有 NN 个操作&#xff0c;所有输入的字符串总长度不超过 105105&#xff0c;字符…

企业微信如何发起视频直播?

一、如何发起直播 1.【工作台->直播 】应用可发起&#xff1b; 【群聊—“”—群直播】可发起&#xff0c;发起直播时&#xff0c;支持预览直播视频&#xff0c;确认开始直播后则进入直播。 2.在直播应用或群聊工具中支持发起预约直播&#xff0c;可设置开始时间、直播时长…

K8s中的ConfigMap

ConfigMap作用&#xff1a;存储不加密数据到etcd&#xff0c;让Pod以变量或者Volume挂载到容器中 场景&#xff1a;配置文件 3.以Vlolume挂载到Pod容器中

【vue】vue的几个提效技巧:

文章目录 一、动态组件结合v-for循环使用【1】使用环境【2】实际使用【3】编译以后的效果 二、watch进阶使用【1】立即执行【2】深度监听 三、计算属性之setter四、$on(hook:生命周期)来简化window监听五、子组件hook:生命周期监听子组件的生命周期回调六、v-pre七、v-once八、…

Three.js给场景添加背景颜色,背景图,全景图

1.相关API的使用&#xff1a; 1 THREE.Color &#xff08;用于创建和表示颜色&#xff09; 2. THREE.TextureLoader&#xff08;用于加载和处理图片纹理&#xff09; 3. THREE.SphereGeometry&#xff08;用于创建一个球体的几何体&#xff09; 4. THREE.Mesh&#xff08;用…

【C# 基础精讲】条件语句:if、else、switch

条件语句是C#编程中用于根据条件执行不同代码块的关键结构。C#支持if、else和switch三种常见的条件语句&#xff0c;它们允许根据表达式的结果决定程序的执行路径。在本文中&#xff0c;我们将详细介绍这三种条件语句的语法和使用方法。 if语句 if语句用于在给定条件为真&…

有奖活动 | 大咖论道:一同畅聊鸿蒙生态

点击预约直播 活动简介 即日起-2023年9月5日&#xff0c;参与本期活动与大咖一起聊聊鸿蒙新生态&#xff0c;您可以在社区写下对鸿蒙生态的畅想&#xff0c;也可以学习相关课程并获取证书&#xff0c;完成活动任务即可参与精美礼品抽奖。 活动周期 8月1日-9月5日 参与考试 Harm…

逻辑卷扩容

背景 服务器有3个逻辑卷&#xff0c;1个是1T&#xff0c;另外两个是500G&#xff0c;需要将500G的合并扩容为1T 操作 df -Th lsblk -f 查看磁盘大小卸载 /approot umount /approot vim /etc/fstab #注释掉/approot mount -a检查是否卸载完成 vgdisplay -v 找到approot所在…

重磅!官方Android现代开发指南发布!

重磅&#xff01;官方Android现代开发指南发布&#xff01; 最近查看了google官方Android开发站点&#xff0c;猛然发现页面做了一些改动&#xff0c;新增了一个专题tab页&#xff0c;增加了一个UI开发指南模块&#xff0c;该模块整合了Jetpack Compose、Jetpack架构组件及Mat…

elementui实现当前页全选+所有全选+翻页保持选中状

原文来自&#xff1a;https://blog.csdn.net/sumimg/article/details/121693305?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-121693305-blog-127570059.235%5Ev38%5Epc_relevant_anti_t3&depth_1-utm…

使用 Python 和 Flask 构建简单的 Restful API 第 1 部分

一、说明 我将把这个系列分成 3 或 4 篇文章。在本系列的最后&#xff0c;您将了解使用flask构建 restful API 是多么容易。在本文中&#xff0c;我们将设置环境并创建将显示“Hello World”的终结点。 我假设你的电脑上安装了python 2.7和pip。我已经在python 2.7上测试了本文…

2023 华数杯全国大学生数学建模竞赛 ——C题母亲身心健康对婴儿成长的影响 完整建模+代码

目录 完整思路下载链接&#xff1a;这里可以获取2023华数杯全国大学生数学建模竞赛题目C 题母亲身心健康对婴儿成长的影响✅ 问题1问题1建模思路✅ 问题2问题2建模思路✅ 问题3问题3建模思路✅ 问题4问题4建模思路✅ 问题5问题5建模思路提供的数据和资料&#xff1a; 完整思路下…

【我们一起60天准备考研算法面试(大全)-第四十天 40/60】【并查集】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

el-table实现指定列合并

table传入span-method方法可以实现合并行或列&#xff0c;方法的参数是一个对象&#xff0c;里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组&#xff0c;第一个元素代表rowspan&#xff0c;第二个元素…

ESP 32 蓝牙虚拟键盘链接笔记本电脑的键值问题

由于打算利用esp32 通过蓝牙链接电脑后实现一些特俗的键盘功能&#xff0c;所以就折腾了一下&#xff0c;折腾最耗费时间的却是键值问题&#xff0c;让一个20多年的老司机重新补充了知识 过程曲折就不说了&#xff0c;直接说结果。 我们通过网络搜索获取的键值和蓝牙模拟键盘传…

云专线的应用场景

云专线是连接用户本地数据中心和云上虚拟私有云的高安全、高速度、低延迟、稳定可靠的专属连接通道&#xff0c;主要有以下应用场景。 1、混合云环境&#xff1a;企业在私有云和公有云之间传输数据及部署应用时&#xff0c;使用云专线建立专用的网络连接&#xff0c;保证数据传…

做赴日IT工作 Java Python等语言哪个更好?

很多同学问我&#xff0c;做赴日IT工作Java&#xff0c;Python等语言哪个更好&#xff1f;更容易拿到内定通知书&#xff1f;如果你想去做赴日IT工作&#xff0c;无论是学Java还是Python或是其他编程语言&#xff0c;都是很好的选择&#xff0c;因为它们都有自己的的前景和应用…