C++中string字符串类型介绍及数组模拟
1. 简介
C语言中通过字符相连已经基本创造出了字符串的常规操作,然而,字符串在C语言中并不是常规类型,而是一个类似于数组的结构,在C++中,通过模板类的操作创建了string类,这样的方法更适合于现代的操作编程。
2. 头文件&命名空间
注意不是<string.h>也不是<cstring>,前者为C文件中的头文件,后者为C++中调用的C文件。
string来自于std命名空间,常用的绝大多数操作均来自这个空间,string也不例外。
using namespace std; //命名空间
3. 初始化
与STL内容十分相近,两者的创建方法基本完全相等,这里直接使用代码举例,不多做缀数。
#include<iostream>
#include<string>
using namespace std;
int main(){
string str; //创建空字符串
string str1 = "Hello ";
cout<<str1<<endl;
string str2(str1);
cout<<str2<<endl;
string str3(str1,6);
cout<<str3<<endl;
string str4(str1,6,6);
cout<<str4<<endl;
string str5(5,'D');
cout<<str5<<endl;
string str6(str1.begin(),str1.end());
cout<<str6<<endl;
return 0;
}
4. 比较与连接操作操作
对于比较类型的操作,可以使用 ==,>,<,>=,<=与!=进行比较字符串,对于链接操作而言,可以直接使用符号+进行直接的操作符连接
比较:对于C语言的字符串操作而言,我们通过使用strcmp函数进行比较,通过这个函数的返回值判断两字符串的大小情况,这样的比较方式确实已经满足了很多功能,但是还不如我们常规的思路,C++中利用符号重载的思路重构了比较方法,直接通过str1==str2的以及相关的方式进行比较,这比较符合我们大多数情况的人类思维,如:
string str1 = "Hello";
string str2 = "Hello";
if(str1==str2)
cout<<"两者相等"<<endl;
else
cout<<"两者不相等"<<endl;
对于字符串的连接操作,对于C语言而言需要使用字符串连接函数,同理,C++使用符号重载直接让我们通过‘+’号完成操作,这也更符合我们的思维,避免了麻烦。
string totalystring = "a";
cout<<totalystring+ "b"+"c"+"d"<<endl;
5. 常用操作(节选)
a) 获取长度length
获取当前字符串的长度,这与C中的strlen(str)一致。
str.length();
b)获取大小size
获取当前字符串的大小,某种意义上由于字符串的每一个字符开辟的空间均完全相等,因此size可以代替length
str.empty();
c) 判断是否为空empty
返回一个布尔类型,判断字符串是否为空empty。
d) 填充内容resize
原型为void resize(int len,char chr)把字符串当前大小置为len,多去少补,多出的字符chr填充不足的部分,resize将会修改该字符串的占用空间。
输出
string str = "HEllo";
str.resize(8,'K');
cout<<str<<endl;
HElloKKK
6. 数据概念
数组这个概念并不陌生,然而,数组本身也是一种数据结构。
数组在存储数据时是按顺序存储的,存储数据的内存也是连续的,所以他的特点就是寻址读取数据比较容易,插入和删除比较困难。简单解释一下为什么,在读取数据时,只需要告诉数组要从哪个位置(索引)取数据就可以了,数组会直接把你想要的位置的数据取出来给你。插入和删除比较困难是因为这些存储数据的内存是连续的,要插入和删除就需要变更整个数组中的数据的位置。
所以数组对比链表,数组读取和使用更加灵活,而链表插入和删除更加便捷。
7. 回到数组
相比在学习各种计算机编程语言基础的时候基本都会了解数组的概念,熟悉数组的使用很重要,在学习数据结构之后尤其是学习到了向量,线性表,链表等概念之后,会更加趋向于使用这类高级数据结构。但在实际中,编程应该讲究灵活贯通,链表等虽然操作方便,但是其由于指针以及其他结构的设计问题本身占用空间就比较大,因此,灵活掌握合适的数据结构的使用是必须的。
8. 模拟
既然了解了数组的优点,为什么不加以善用呢?这里介绍一个编程的思维——模拟,所谓模拟,就是通过简单易懂的方式,根据所给出的要求,一一进行实现,通过代码模拟出所需要实现的方法过程,模拟的方法不是一种具体的实现算法,而是一种思维。
如分糖果题目
我们通过模拟的思路,通过创建一个数组,每一个数组元素代表有一个小朋友,利用while循环的判断来筛选出跳出条件的方式来完成,参考代码如下:
#include<iostream>
using namespace std;
const int MAX=101;
int kid[MAX],ans=0;
int main() {
int n;
cin>>n;
for(int i=0; i<n; i++) {
cin>>kid[i];
}
while(1) {
//用于判断是否全体相等,如果全体相等则退出循环,期待有更好的方式解决
bool flag=true;
for(int i=1; i<n; i++) {
if(kid[0]!=kid[i])
flag=false;
}
if(flag)
break;
//全体减半(由于是全体偶数,所以不需要考虑进位问题)
for(int i=0; i<n; i++) {
kid[i]=kid[i]/2;
}
//利用一个临时变量来将全体数组加上前面一位的数
int temp=kid[n-1];
for(int i=n-1; i>0; i--) {
kid[i]+=kid[i-1];
}
kid[0]+=temp;
//判断是否是偶数,不是则+1,同时计数器也+1
for(int i=0; i<n; i++) {
if(kid[i]%2!=0) {
kid[i]++;
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}
诸如此类,还有很多类似的题目,多多进行研究对代码书些很有帮助。